Evaluate some deltas
This commit is contained in:
parent
0eda941ed7
commit
b8aeb79323
2 changed files with 143 additions and 5 deletions
18
src/eval.rs
18
src/eval.rs
|
|
@ -3,7 +3,7 @@ use std::result;
|
||||||
|
|
||||||
use chrono::{Datelike, NaiveDate};
|
use chrono::{Datelike, NaiveDate};
|
||||||
|
|
||||||
use crate::files::commands::{Birthday, Command, DoneDate, Note, Spec, Task};
|
use crate::files::commands::{Birthday, Command, DoneDate, Note, Span, Spec, Task, Time};
|
||||||
use crate::files::{Files, Source, SourcedCommand};
|
use crate::files::{Files, Source, SourcedCommand};
|
||||||
|
|
||||||
use self::entry::EntryMap;
|
use self::entry::EntryMap;
|
||||||
|
|
@ -16,10 +16,20 @@ mod entry;
|
||||||
mod formula_spec;
|
mod formula_spec;
|
||||||
mod range;
|
mod range;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("TODO")]
|
DeltaInvalidStep {
|
||||||
Todo,
|
span: Span,
|
||||||
|
start: NaiveDate,
|
||||||
|
start_time: Option<Time>,
|
||||||
|
prev: NaiveDate,
|
||||||
|
prev_time: Option<Time>,
|
||||||
|
},
|
||||||
|
DeltaNoTime {
|
||||||
|
span: Span,
|
||||||
|
start: NaiveDate,
|
||||||
|
prev: NaiveDate,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::files::commands::{self, Spanned, Time, Weekday};
|
use chrono::{Datelike, Duration, NaiveDate};
|
||||||
|
|
||||||
|
use crate::files::commands::{self, Span, Spanned, Time, Weekday};
|
||||||
|
|
||||||
|
use super::{Error, Result};
|
||||||
|
|
||||||
/// Like [`commands::DeltaStep`] but includes a new constructor,
|
/// Like [`commands::DeltaStep`] but includes a new constructor,
|
||||||
/// [`DeltaStep::Time`].
|
/// [`DeltaStep::Time`].
|
||||||
|
|
@ -137,6 +141,122 @@ impl From<&commands::Delta> for Delta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DeltaEval {
|
||||||
|
start: NaiveDate,
|
||||||
|
start_time: Option<Time>,
|
||||||
|
curr: NaiveDate,
|
||||||
|
curr_time: Option<Time>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeltaEval {
|
||||||
|
fn new(start: NaiveDate, start_time: Option<Time>) -> Self {
|
||||||
|
Self {
|
||||||
|
start,
|
||||||
|
start_time,
|
||||||
|
curr: start,
|
||||||
|
curr_time: start_time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err_step(&self, span: Span) -> Error {
|
||||||
|
Error::DeltaInvalidStep {
|
||||||
|
span,
|
||||||
|
start: self.start,
|
||||||
|
start_time: self.start_time,
|
||||||
|
prev: self.curr,
|
||||||
|
prev_time: self.curr_time,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err_time(&self, span: Span) -> Error {
|
||||||
|
Error::DeltaNoTime {
|
||||||
|
span,
|
||||||
|
start: self.start,
|
||||||
|
prev: self.curr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&mut self, step: &Spanned<DeltaStep>) -> Result<()> {
|
||||||
|
match step.value {
|
||||||
|
DeltaStep::Year(n) => self.step_year(step.span, n),
|
||||||
|
DeltaStep::Month(n) => self.step_month(step.span, n),
|
||||||
|
DeltaStep::MonthReverse(n) => self.step_month_reverse(step.span, n),
|
||||||
|
DeltaStep::Day(n) => self.step_day(step.span, n),
|
||||||
|
DeltaStep::Week(n) => self.step_week(step.span, n),
|
||||||
|
DeltaStep::Hour(n) => self.step_hour(step.span, n),
|
||||||
|
DeltaStep::Minute(n) => self.step_minute(step.span, n),
|
||||||
|
DeltaStep::Weekday(n, wd) => self.step_weekday(step.span, n, wd),
|
||||||
|
DeltaStep::Time(time) => self.step_time(step.span, time),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_year(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
let curr = self.curr;
|
||||||
|
match NaiveDate::from_ymd_opt(curr.year() + amount, curr.month(), curr.day()) {
|
||||||
|
None => Err(self.err_step(span)),
|
||||||
|
Some(next) => {
|
||||||
|
self.curr = next;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_month(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
let month0 = self.curr.month0() as i32 + amount;
|
||||||
|
let year = self.curr.year() + month0.div_euclid(12);
|
||||||
|
let month0 = month0.rem_euclid(12) as u32;
|
||||||
|
match NaiveDate::from_ymd_opt(year, month0 + 1, self.curr.day()) {
|
||||||
|
None => Err(self.err_step(span)),
|
||||||
|
Some(next) => {
|
||||||
|
self.curr = next;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_month_reverse(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_day(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
let delta = Duration::days(amount.into());
|
||||||
|
match self.curr.checked_add_signed(delta) {
|
||||||
|
None => Err(self.err_step(span)),
|
||||||
|
Some(next) => {
|
||||||
|
self.curr = next;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_week(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
let delta = Duration::days((7 * amount).into());
|
||||||
|
match self.curr.checked_add_signed(delta) {
|
||||||
|
None => Err(self.err_step(span)),
|
||||||
|
Some(next) => {
|
||||||
|
self.curr = next;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_hour(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_minute(&mut self, span: Span, amount: i32) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_weekday(&mut self, span: Span, amount: i32, weekday: Weekday) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_time(&mut self, span: Span, time: Time) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Delta {
|
impl Delta {
|
||||||
pub fn lower_bound(&self) -> i32 {
|
pub fn lower_bound(&self) -> i32 {
|
||||||
self.steps.iter().map(|step| step.value.lower_bound()).sum()
|
self.steps.iter().map(|step| step.value.lower_bound()).sum()
|
||||||
|
|
@ -145,4 +265,12 @@ impl Delta {
|
||||||
pub fn upper_bound(&self) -> i32 {
|
pub fn upper_bound(&self) -> i32 {
|
||||||
self.steps.iter().map(|step| step.value.upper_bound()).sum()
|
self.steps.iter().map(|step| step.value.upper_bound()).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply(&self, start: (NaiveDate, Option<Time>)) -> Result<(NaiveDate, Option<Time>)> {
|
||||||
|
let mut eval = DeltaEval::new(start.0, start.1);
|
||||||
|
for step in &self.steps {
|
||||||
|
eval.apply(step)?;
|
||||||
|
}
|
||||||
|
Ok((eval.curr, eval.curr_time))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue