diff --git a/src/eval.rs b/src/eval.rs index 3a36b56..bf6a826 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -7,6 +7,7 @@ use crate::files::commands::{Birthday, Command, File, Note, Spec, Task}; use self::entries::{DateRange, Entry, EntryKind, EntryMap}; +mod delta; pub mod entries; #[derive(Debug, thiserror::Error)] diff --git a/src/eval/delta.rs b/src/eval/delta.rs new file mode 100644 index 0000000..f2d5095 --- /dev/null +++ b/src/eval/delta.rs @@ -0,0 +1,95 @@ +use std::cmp::Ordering; + +use crate::files::commands::{Delta, DeltaStep}; + +impl DeltaStep { + fn lower_bound(&self) -> i32 { + match self { + DeltaStep::Year(n) => { + if *n < 0 { + *n * 366 + } else { + *n * 365 + } + } + DeltaStep::Month(n) | DeltaStep::MonthReverse(n) => { + if *n < 0 { + *n * 31 + } else { + *n * 28 + } + } + DeltaStep::Day(n) => *n, + DeltaStep::Week(n) => *n * 7, + DeltaStep::Hour(n) => { + if *n < 0 { + *n / 24 + (*n % 24).signum() + } else { + *n / 24 + } + } + DeltaStep::Minute(n) => { + if *n < 0 { + *n / (24 * 60) + (*n % (24 * 60)).signum() + } else { + *n / (24 * 60) + } + } + DeltaStep::Weekday(n, _) => match n.cmp(&0) { + Ordering::Less => *n * 7 - 1, + Ordering::Equal => 0, + Ordering::Greater => *n * 7 - 7, + }, + } + } + + fn upper_bound(&self) -> i32 { + match self { + DeltaStep::Year(n) => { + if *n > 0 { + *n * 366 + } else { + *n * 365 + } + } + DeltaStep::Month(n) | DeltaStep::MonthReverse(n) => { + if *n > 0 { + *n * 31 + } else { + *n * 28 + } + } + DeltaStep::Day(n) => *n, + DeltaStep::Week(n) => *n * 7, + DeltaStep::Hour(n) => { + if *n > 0 { + *n / 24 + (*n % 24).signum() + } else { + *n / 24 + } + } + DeltaStep::Minute(n) => { + if *n > 0 { + *n / (24 * 60) + (*n % (24 * 60)).signum() + } else { + *n / (24 * 60) + } + } + DeltaStep::Weekday(n, _) => match n.cmp(&0) { + Ordering::Less => *n * 7 - 7, + Ordering::Equal => 0, + Ordering::Greater => *n * 7 - 1, + }, + } + } +} + +impl Delta { + pub fn lower_bound(&self) -> i32 { + self.0.iter().map(DeltaStep::lower_bound).sum() + } + + pub fn upper_bound(&self) -> i32 { + self.0.iter().map(DeltaStep::upper_bound).sum() + } +}