From e827556c8446b8c770cb800e3dfa950a140f66b8 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 25 Nov 2021 02:32:08 +0100 Subject: [PATCH] Add eval representation of FormulaSpec --- src/eval.rs | 26 ++++++++++++++- src/eval/delta.rs | 55 ++++++++++++++++++++++++++++++-- src/eval/entry.rs | 2 +- src/eval/formula_spec.rs | 68 ++++++++++++++++++++++++++++++++++++++++ src/files/commands.rs | 24 +++++++++++--- 5 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 src/eval/formula_spec.rs diff --git a/src/eval.rs b/src/eval.rs index 5731879..8ad87fa 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -3,15 +3,18 @@ use std::result; use chrono::{Datelike, NaiveDate}; +use crate::files::commands::DateSpec; use crate::files::commands::{Birthday, Command, DoneDate, Note, Spec, Task}; use crate::files::{Files, Source, SourcedCommand}; use self::entry::EntryMap; pub use self::entry::{Entry, EntryKind}; +use self::formula_spec::FormulaSpec; pub use self::range::DateRange; mod delta; mod entry; +mod formula_spec; mod range; #[derive(Debug, thiserror::Error)] @@ -28,13 +31,34 @@ struct Eval { } impl Eval { + fn eval_date_spec( + &mut self, + spec: &DateSpec, + last_done: Option, + new_entry: impl Fn(Source, Option) -> Entry, + ) -> Result<()> { + todo!() + } + + fn eval_formula_spec( + &mut self, + spec: FormulaSpec, + new_entry: impl Fn(Source, Option) -> Entry, + ) -> Result<()> { + todo!() + } + fn eval_spec( &mut self, spec: &Spec, last_done: Option, new_entry: impl Fn(Source, Option) -> Entry, ) -> Result<()> { - todo!() + match spec { + Spec::Date(spec) => self.eval_date_spec(spec, last_done, new_entry), + Spec::Weekday(spec) => self.eval_formula_spec(spec.into(), new_entry), + Spec::Formula(spec) => self.eval_formula_spec(spec.into(), new_entry), + } } fn eval_dones(&mut self, task: &Task) { diff --git a/src/eval/delta.rs b/src/eval/delta.rs index f2d5095..f9ddc05 100644 --- a/src/eval/delta.rs +++ b/src/eval/delta.rs @@ -1,8 +1,41 @@ use std::cmp::Ordering; -use crate::files::commands::{Delta, DeltaStep}; +use crate::files::commands::{self, Time, Weekday}; + +/// Like [`commands::DeltaStep`] but includes a new constructor, +/// [`DeltaStep::Time`]. +#[derive(Debug, Clone, Copy)] +pub enum DeltaStep { + Year(i32), + Month(i32), + MonthReverse(i32), + Day(i32), + Week(i32), + Hour(i32), + Minute(i32), + Weekday(i32, Weekday), + /// Set the time to the next occurrence of the specified time. Useful to + /// unify the end delta and end time for different specs. + Time(Time), +} + +impl From for DeltaStep { + fn from(step: commands::DeltaStep) -> Self { + match step { + commands::DeltaStep::Year(n) => Self::Year(n), + commands::DeltaStep::Month(n) => Self::Month(n), + commands::DeltaStep::MonthReverse(n) => Self::MonthReverse(n), + commands::DeltaStep::Day(n) => Self::Day(n), + commands::DeltaStep::Week(n) => Self::Week(n), + commands::DeltaStep::Hour(n) => Self::Hour(n), + commands::DeltaStep::Minute(n) => Self::Minute(n), + commands::DeltaStep::Weekday(n, wd) => Self::Weekday(n, wd), + } + } +} impl DeltaStep { + /// A lower bound on days fn lower_bound(&self) -> i32 { match self { DeltaStep::Year(n) => { @@ -40,9 +73,11 @@ impl DeltaStep { Ordering::Equal => 0, Ordering::Greater => *n * 7 - 7, }, + DeltaStep::Time(_) => 0, } } + /// An upper bound on days fn upper_bound(&self) -> i32 { match self { DeltaStep::Year(n) => { @@ -80,16 +115,30 @@ impl DeltaStep { Ordering::Equal => 0, Ordering::Greater => *n * 7 - 1, }, + DeltaStep::Time(_) => 1, + } + } +} + +#[derive(Debug, Default)] +pub struct Delta { + pub steps: Vec, +} + +impl From<&commands::Delta> for Delta { + fn from(delta: &commands::Delta) -> Self { + Self { + steps: delta.0.iter().map(|&step| step.into()).collect(), } } } impl Delta { pub fn lower_bound(&self) -> i32 { - self.0.iter().map(DeltaStep::lower_bound).sum() + self.steps.iter().map(DeltaStep::lower_bound).sum() } pub fn upper_bound(&self) -> i32 { - self.0.iter().map(DeltaStep::upper_bound).sum() + self.steps.iter().map(DeltaStep::upper_bound).sum() } } diff --git a/src/eval/entry.rs b/src/eval/entry.rs index 292a1df..98f8fb9 100644 --- a/src/eval/entry.rs +++ b/src/eval/entry.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use chrono::NaiveDate; -use crate::files::commands::{DoneDate, Time}; +use crate::files::commands::DoneDate; use crate::files::Source; use super::range::DateRange; diff --git a/src/eval/formula_spec.rs b/src/eval/formula_spec.rs new file mode 100644 index 0000000..569c513 --- /dev/null +++ b/src/eval/formula_spec.rs @@ -0,0 +1,68 @@ +use crate::files::commands::{self, Expr, Time, Var}; + +use super::delta::{Delta, DeltaStep}; + +pub struct FormulaSpec { + // TODO Implement more efficient exprs and expr evaluation + pub start: Expr, + pub start_delta: Delta, + pub start_time: Option