Fix out-of-range move commands

This commit is contained in:
Joscha 2021-12-12 19:09:38 +00:00
parent 240becd28d
commit 6f1a533b95
4 changed files with 39 additions and 3 deletions

View file

@ -25,8 +25,8 @@ pub fn run() -> anyhow::Result<()> {
let now = files.now().naive_local(); let now = files.now().naive_local();
let range = DateRange::new( let range = DateRange::new(
NaiveDate::from_ymd(2021, 1, 1), NaiveDate::from_ymd(2021, 12, 12 - 3),
NaiveDate::from_ymd(2022, 12, 31), NaiveDate::from_ymd(2021, 12, 12 + 13),
) )
.unwrap(); .unwrap();

View file

@ -25,7 +25,20 @@ pub struct CommandState<'a> {
} }
impl<'a> CommandState<'a> { impl<'a> CommandState<'a> {
pub fn new(command: SourcedCommand<'a>, range: DateRange) -> Self { pub fn new(command: SourcedCommand<'a>, mut range: DateRange) -> Self {
// If we don't calculate entries for the source of the move command, it
// fails even though the user did nothing wrong. Also, move commands (or
// chains thereof) may move an initially out-of-range entry into range.
//
// To fix this, we just expand the range to contain all move command
// sources. This is a quick fix, but until it becomes a performance
// issue (if ever), it's probably fine.
for statement in command.command.statements() {
if let Statement::Move { from, .. } = statement {
range = range.containing(*from)
}
}
Self { Self {
range, range,
command, command,

View file

@ -28,6 +28,22 @@ impl DateRange {
Self::new(self.from, until) Self::new(self.from, until)
} }
pub fn containing(&self, date: NaiveDate) -> Self {
if date < self.from {
Self {
from: date,
until: self.until,
}
} else if self.until < date {
Self {
from: self.from,
until: date,
}
} else {
*self
}
}
pub fn contains(&self, date: NaiveDate) -> bool { pub fn contains(&self, date: NaiveDate) -> bool {
self.from <= date && date <= self.until self.from <= date && date <= self.until
} }

View file

@ -325,6 +325,13 @@ impl Command {
Self::Note(note) => &note.desc, Self::Note(note) => &note.desc,
} }
} }
pub fn statements(&self) -> &[Statement] {
match self {
Self::Task(task) => &task.statements,
Self::Note(note) => &note.statements,
}
}
} }
#[derive(Debug)] #[derive(Debug)]