diff --git a/src/eval/delta.rs b/src/eval/delta.rs index 6221a77..423c587 100644 --- a/src/eval/delta.rs +++ b/src/eval/delta.rs @@ -7,6 +7,8 @@ use crate::files::primitives::{Span, Spanned, Time, Weekday}; use super::{util, Error, Result}; +// TODO Test all these delta steps + /// Like [`commands::DeltaStep`] but includes a new constructor, /// [`DeltaStep::Time`]. #[derive(Debug, Clone, Copy)] @@ -239,11 +241,27 @@ impl DeltaEval { } fn step_hour(&mut self, span: Span, amount: i32) -> Result<()> { - todo!() + let time = match self.curr_time { + Some(time) => time, + None => return Err(self.err_time(span)), + }; + + let (days, time) = time.add_hours(amount); + self.curr += Duration::days(days.into()); + self.curr_time = Some(time); + Ok(()) } fn step_minute(&mut self, span: Span, amount: i32) -> Result<()> { - todo!() + let time = match self.curr_time { + Some(time) => time, + None => return Err(self.err_time(span)), + }; + + let (days, time) = time.add_minutes(amount); + self.curr += Duration::days(days.into()); + self.curr_time = Some(time); + Ok(()) } fn step_weekday(&mut self, amount: i32, weekday: Weekday) { @@ -261,7 +279,16 @@ impl DeltaEval { } fn step_time(&mut self, span: Span, time: Time) -> Result<()> { - todo!() + let curr_time = match self.curr_time { + Some(time) => time, + None => return Err(self.err_time(span)), + }; + + if time < curr_time { + self.curr = self.curr.succ(); + } + self.curr_time = Some(time); + Ok(()) } } diff --git a/src/files/primitives.rs b/src/files/primitives.rs index 8fb34c6..cc93a77 100644 --- a/src/files/primitives.rs +++ b/src/files/primitives.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use std::fmt; #[derive(Debug, Clone, Copy)] @@ -64,6 +65,42 @@ impl Time { None } } + + pub fn add_minutes(&self, amount: i32) -> (i32, Self) { + match amount.cmp(&0) { + Ordering::Less => { + let mut mins = (self.hour as i32) * 60 + (self.min as i32) + amount; + + let days = mins.div_euclid(60 * 24); + mins = mins.rem_euclid(60 * 24); + + let hour = mins.div_euclid(60) as u32; + let min = mins.rem_euclid(60) as u32; + (days, Self::new(hour, min).unwrap()) + } + Ordering::Greater => { + let mut mins = (self.hour as i32) * 60 + (self.min as i32) + amount; + + let mut days = mins.div_euclid(60 * 24); + mins = mins.rem_euclid(60 * 24); + + // Correct days and minutes so we get 24:00 instead of 00:00 + if mins == 0 { + days -= 1; + mins = 60 * 24; + } + + let hour = mins.div_euclid(60) as u32; + let min = mins.rem_euclid(60) as u32; + (days, Self::new(hour, min).unwrap()) + } + Ordering::Equal => (0, *self), + } + } + + pub fn add_hours(&self, amount: i32) -> (i32, Self) { + self.add_minutes(amount * 60) + } } #[derive(Debug, Clone, Copy)]