Collect relevant entries based on different modes
This commit is contained in:
parent
b8aeb79323
commit
f42027e378
3 changed files with 122 additions and 11 deletions
16
src/eval.rs
16
src/eval.rs
|
|
@ -60,7 +60,7 @@ impl Eval {
|
|||
title: task.title.clone(),
|
||||
desc: task.desc.clone(),
|
||||
source: self.source,
|
||||
date: done.date,
|
||||
root: done.date,
|
||||
};
|
||||
self.map.insert(entry);
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ impl Eval {
|
|||
title: task.title.clone(),
|
||||
desc: task.desc.clone(),
|
||||
source: self.source,
|
||||
date: None,
|
||||
root: None,
|
||||
});
|
||||
} else {
|
||||
let last_done = Self::determine_last_done(task);
|
||||
|
|
@ -130,7 +130,7 @@ impl Eval {
|
|||
title: task.title.clone(),
|
||||
desc: task.desc.clone(),
|
||||
source,
|
||||
date,
|
||||
root: date,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +162,7 @@ impl Eval {
|
|||
title: note.title.clone(),
|
||||
desc: note.desc.clone(),
|
||||
source: self.source,
|
||||
date: None,
|
||||
root: None,
|
||||
});
|
||||
} else {
|
||||
if let Some(range) = self.determine_note_range(note) {
|
||||
|
|
@ -181,7 +181,7 @@ impl Eval {
|
|||
title: note.title.clone(),
|
||||
desc: note.desc.clone(),
|
||||
source,
|
||||
date,
|
||||
root: date,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +207,7 @@ impl Eval {
|
|||
title: title.clone(),
|
||||
desc: birthday.desc.clone(),
|
||||
source: self.source,
|
||||
date: Some(DoneDate::Date { root: date }),
|
||||
root: Some(DoneDate::Date { root: date }),
|
||||
};
|
||||
self.map.insert(entry);
|
||||
} else {
|
||||
|
|
@ -220,7 +220,7 @@ impl Eval {
|
|||
title: format!("{} (first half)", title),
|
||||
desc: birthday.desc.clone(),
|
||||
source: self.source,
|
||||
date: Some(DoneDate::Date { root: date }),
|
||||
root: Some(DoneDate::Date { root: date }),
|
||||
};
|
||||
self.map.insert(entry);
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ impl Eval {
|
|||
title: format!("{} (second half)", title),
|
||||
desc: birthday.desc.clone(),
|
||||
source: self.source,
|
||||
date: Some(DoneDate::Date { root: date }),
|
||||
root: Some(DoneDate::Date { root: date }),
|
||||
};
|
||||
self.map.insert(entry);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,95 @@ pub struct Entry {
|
|||
pub desc: Vec<String>,
|
||||
|
||||
pub source: Source,
|
||||
pub date: Option<DoneDate>,
|
||||
pub root: Option<DoneDate>,
|
||||
}
|
||||
|
||||
/// Mode that determines how entries are filtered when they are added to
|
||||
/// an [`Entries`].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum EntryMode {
|
||||
/// The entry's root date must be contained in the range.
|
||||
Rooted,
|
||||
/// The entry must overlap the range.
|
||||
Touching,
|
||||
/// The entry must be in some way relevant to the range. It may
|
||||
/// - touch the range,
|
||||
/// - be an unfinished task that lies before the range,
|
||||
/// - be a finished task that was completed inside the range, or
|
||||
/// - have no root date.
|
||||
Relevant,
|
||||
}
|
||||
|
||||
pub struct Entries {
|
||||
mode: EntryMode,
|
||||
range: DateRange,
|
||||
entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
impl Entries {
|
||||
pub fn new(mode: EntryMode, range: DateRange) -> Self {
|
||||
Self {
|
||||
mode,
|
||||
range,
|
||||
entries: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn is_rooted(&self, entry: &Entry) -> bool {
|
||||
match entry.root {
|
||||
Some(date) => self.range.contains(date.root()),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_touching(&self, entry: &Entry) -> bool {
|
||||
if let Some(date) = entry.root {
|
||||
// Inside the range or overlapping it
|
||||
date.first() <= self.range.until() && self.range.from() <= date.last()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_relevant(&self, entry: &Entry) -> bool {
|
||||
if entry.root.is_none() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Anything close to the range
|
||||
if self.is_touching(entry) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tasks that were finished inside the range
|
||||
if let EntryKind::TaskDone(done) = entry.kind {
|
||||
if self.range.contains(done) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Unfinished tasks before or inside the range
|
||||
if let EntryKind::Task = entry.kind {
|
||||
if let Some(date) = entry.root {
|
||||
if date.first() <= self.range.until() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn add(&mut self, entry: Entry) {
|
||||
let keep = match self.mode {
|
||||
EntryMode::Rooted => self.is_rooted(&entry),
|
||||
EntryMode::Touching => self.is_touching(&entry),
|
||||
EntryMode::Relevant => self.is_relevant(&entry),
|
||||
};
|
||||
if keep {
|
||||
self.entries.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EntryMap {
|
||||
|
|
@ -47,7 +135,7 @@ impl EntryMap {
|
|||
}
|
||||
|
||||
pub fn insert(&mut self, entry: Entry) {
|
||||
if let Some(date) = entry.date {
|
||||
if let Some(date) = entry.root {
|
||||
let date = date.root();
|
||||
if self.range.contains(date) {
|
||||
self.map.entry(date).or_insert(Some(entry));
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::fmt;
|
||||
use std::{cmp, fmt};
|
||||
|
||||
use chrono::NaiveDate;
|
||||
|
||||
|
|
@ -372,6 +372,29 @@ impl DoneDate {
|
|||
DoneDate::DateToDateWithTime { root, .. } => *root,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn other(&self) -> Option<NaiveDate> {
|
||||
match self {
|
||||
DoneDate::Date { .. } => None,
|
||||
DoneDate::DateWithTime { .. } => None,
|
||||
DoneDate::DateToDate { other, .. } => Some(*other),
|
||||
DoneDate::DateToDateWithTime { other, .. } => Some(*other),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn first(&self) -> NaiveDate {
|
||||
match self.other() {
|
||||
None => self.root(),
|
||||
Some(other) => cmp::min(self.root(), other),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last(&self) -> NaiveDate {
|
||||
match self.other() {
|
||||
None => self.root(),
|
||||
Some(other) => cmp::max(self.root(), other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue