Implement basic structure for note evaluation

This commit is contained in:
Joscha 2021-11-24 02:05:31 +01:00
parent 8034ec19cd
commit 0bb01369b8
2 changed files with 69 additions and 15 deletions

View file

@ -3,8 +3,8 @@ use std::result;
use chrono::{Datelike, NaiveDate}; use chrono::{Datelike, NaiveDate};
use crate::eval::entry::EntryDate; use crate::eval::entry::EntryDate;
use crate::files::commands::{Birthday, Command}; use crate::files::commands::{Birthday, Command, Note, Spec, Task};
use crate::files::{Files, Source}; use crate::files::{Files, Source, SourcedCommand};
use self::entry::{Entry, EntryKind, EntryMap}; use self::entry::{Entry, EntryKind, EntryMap};
pub use self::range::DateRange; pub use self::range::DateRange;
@ -27,11 +27,55 @@ struct Eval {
} }
impl Eval { impl Eval {
pub fn new(range: DateRange, source: Source) -> Self { fn eval_spec(
Self { &mut self,
map: EntryMap::new(range), spec: &Spec,
source, new_entry: impl Fn(Source, EntryDate) -> Entry,
) -> Result<()> {
todo!()
} }
fn eval_note(&mut self, note: &Note) -> Result<()> {
if note.when.is_empty() {
let entry = Entry {
kind: EntryKind::Note,
title: note.title.clone(),
desc: note.desc.clone(),
source: self.source,
date: EntryDate::None,
};
self.map.insert(entry);
} else {
if let Some(from) = note.from {
if self.map.range().until() < from {
return Ok(());
}
if self.map.range().from() < from {
self.map.set_from(from);
}
}
if let Some(until) = note.until {
if until < self.map.range().from() {
return Ok(());
}
if until < self.map.range().until() {
self.map.set_until(until);
}
}
for except in &note.except {
self.map.block(*except);
}
for spec in &note.when {
self.eval_spec(spec, |source, date| Entry {
kind: EntryKind::Note,
title: note.title.clone(),
desc: note.desc.clone(),
source,
date,
})?;
}
}
Ok(())
} }
fn eval_birthday(&mut self, birthday: &Birthday) { fn eval_birthday(&mut self, birthday: &Birthday) {
@ -83,15 +127,17 @@ impl Eval {
} }
} }
pub fn eval(&mut self, command: &Command) -> Result<Vec<Entry>> { pub fn eval(range: DateRange, command: &SourcedCommand<'_>) -> Result<Vec<Entry>> {
// This function fills the entry map and then drains it again, so in let mut map = Self {
// theory, the struct can even be reused afterwards. map: EntryMap::new(range),
match command { source: command.source,
Command::Task(task) => todo!(), };
Command::Note(note) => todo!(), match command.command {
Command::Birthday(birthday) => self.eval_birthday(birthday), Command::Task(task) => map.eval_task(task)?,
Command::Note(note) => map.eval_note(note)?,
Command::Birthday(birthday) => map.eval_birthday(birthday),
} }
Ok(self.map.drain()) Ok(map.map.drain())
} }
} }
@ -99,7 +145,7 @@ impl Files {
pub fn eval(&self, range: DateRange) -> Result<Vec<Entry>> { pub fn eval(&self, range: DateRange) -> Result<Vec<Entry>> {
let mut result = vec![]; let mut result = vec![];
for command in self.commands() { for command in self.commands() {
result.append(&mut Eval::new(range, command.source).eval(command.command)?); result.append(&mut Eval::eval(range, &command)?);
} }
Ok(result) Ok(result)
} }

View file

@ -78,6 +78,14 @@ impl EntryMap {
self.range self.range
} }
pub fn set_from(&mut self, from: NaiveDate) {
self.range = DateRange::new(from, self.range.until());
}
pub fn set_until(&mut self, until: NaiveDate) {
self.range = DateRange::new(self.range.from(), until);
}
pub fn block(&mut self, date: NaiveDate) { pub fn block(&mut self, date: NaiveDate) {
if self.range.contains(date) { if self.range.contains(date) {
self.map.entry(date).or_insert(None); self.map.entry(date).or_insert(None);