use proto::MainCityTimeBin; #[derive(Clone)] pub struct MainCityTime { pub day_of_week: DayOfWeek, pub time_of_day: TimeOfDay, } impl MainCityTime { const DEFAULT_DAY: u32 = 1; const DEFAULT_TIME: u32 = 1080; pub fn tick(&mut self) { if self.time_of_day.tick() { self.day_of_week.next(); } } pub fn fast_forward(&mut self, minutes: u32) { let days_passed = self.time_of_day.fast_forward(minutes); self.day_of_week.fast_forward(days_passed) } pub fn to_bin(&self) -> MainCityTimeBin { MainCityTimeBin { minutes: self.time_of_day.value(), day: self.day_of_week.value(), } } pub fn from_bin(bin: MainCityTimeBin) -> Self { Self { time_of_day: TimeOfDay::new(bin.minutes), day_of_week: DayOfWeek::new(bin.day), } } } impl Default for MainCityTime { fn default() -> Self { Self { day_of_week: DayOfWeek::new(Self::DEFAULT_DAY), time_of_day: TimeOfDay::new(Self::DEFAULT_TIME), } } } #[derive(Clone)] pub struct DayOfWeek(u32); #[derive(Clone)] pub struct TimeOfDay(u32); impl DayOfWeek { const DAYS: u32 = 7; pub fn new(day: u32) -> Self { Self(day % Self::DAYS) } pub fn value(&self) -> u32 { self.0 } pub fn next(&mut self) { self.0 = (self.0 + 1) % Self::DAYS } pub fn fast_forward(&mut self, days: u32) { self.0 = (self.0 + days) % Self::DAYS } } impl TimeOfDay { const TIME_PERIOD: u32 = 1440; pub fn new(minutes: u32) -> Self { Self(minutes % Self::TIME_PERIOD) } pub fn value(&self) -> u32 { self.0 } pub fn is_zero(&self) -> bool { (self.0 % Self::TIME_PERIOD) == 0 } pub fn tick(&mut self) -> bool { self.0 = (self.0 + 1) % Self::TIME_PERIOD; self.is_zero() } pub fn fast_forward(&mut self, minutes: u32) -> u32 { self.0 += minutes; let days_passed = self.0 / Self::TIME_PERIOD; self.0 %= Self::TIME_PERIOD; days_passed } }