Move entries to a different time

This commit is contained in:
Joscha 2021-12-21 19:24:27 +01:00
parent 05a4582f13
commit 1ac39c69f2
9 changed files with 99 additions and 26 deletions

View file

@ -1,11 +1,11 @@
use std::collections::HashMap;
use chrono::NaiveDate;
use chrono::{Duration, NaiveDate};
use crate::files::commands::{
self, BirthdaySpec, Command, Done, DoneDate, Note, Spec, Statement, Task,
};
use crate::files::primitives::{Span, Spanned};
use crate::files::primitives::{Span, Spanned, Time};
use crate::files::SourcedCommand;
use super::date::Dates;
@ -220,7 +220,12 @@ impl<'a> CommandState<'a> {
Statement::From(date) => self.from = *date,
Statement::Until(date) => self.until = *date,
Statement::Except(date) => self.eval_except(*date),
Statement::Move { span, from, to } => self.eval_move(*span, *from, *to)?,
Statement::Move {
span,
from,
to,
to_time,
} => self.eval_move(*span, *from, *to, *to_time)?,
Statement::Remind(delta) => self.eval_remind(delta),
}
Ok(())
@ -242,13 +247,31 @@ impl<'a> CommandState<'a> {
self.dated.remove(&date);
}
fn eval_move(&mut self, span: Span, from: NaiveDate, to: NaiveDate) -> Result<()> {
fn eval_move(
&mut self,
span: Span,
from: NaiveDate,
to: Option<NaiveDate>,
to_time: Option<Time>,
) -> Result<()> {
if let Some(mut entry) = self.dated.remove(&from) {
if let Some(dates) = entry.dates {
let delta = to - from;
entry.dates = Some(dates.move_by(delta));
let mut dates = entry.dates.expect("comes from self.dated");
// Determine delta
let mut delta = Duration::zero();
if let Some(to) = to {
delta = delta + (to - dates.root());
}
self.dated.insert(to, entry);
if let Some(to_time) = to_time {
if let Some((root, _)) = dates.times() {
delta = delta + Duration::minutes(root.minutes_to(to_time));
}
}
dates = dates.move_by(delta);
entry.dates = Some(dates);
self.dated.insert(dates.root(), entry);
Ok(())
} else {
Err(Error::MoveWithoutSource {

View file

@ -103,11 +103,24 @@ impl Dates {
}
pub fn move_by(&self, delta: Duration) -> Self {
Self {
root: self.root + delta,
other: self.other + delta,
times: self.times,
let mut result = *self;
// Modify dates
result.root += delta;
result.other += delta;
// Modify times if necessary (may further modify dates)
const MINUTES_PER_DAY: i64 = 24 * 60;
let minutes = delta.num_minutes() % MINUTES_PER_DAY; // May be negative
if let Some(times) = self.times {
let (root_days, root) = times.root.add_minutes(minutes);
let (other_days, other) = times.other.add_minutes(minutes);
result.root += Duration::days(root_days);
result.other += Duration::days(other_days);
result.times = Some(Times { root, other });
}
result
}
}

View file

@ -258,8 +258,8 @@ impl DeltaEval {
None => return Err(self.err_time(span)),
};
let (days, time) = time.add_hours(amount);
self.curr += Duration::days(days.into());
let (days, time) = time.add_hours(amount.into());
self.curr += Duration::days(days);
self.curr_time = Some(time);
Ok(())
}
@ -270,8 +270,8 @@ impl DeltaEval {
None => return Err(self.err_time(span)),
};
let (days, time) = time.add_minutes(amount);
self.curr += Duration::days(days.into());
let (days, time) = time.add_minutes(amount.into());
self.curr += Duration::days(days);
self.curr_time = Some(time);
Ok(())
}