diff --git a/src/tasks.rs b/src/tasks.rs index 95f8715..7a95c3f 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -86,18 +86,16 @@ impl Tasks { } fn total_progress(&self, id: &EventId) -> Option { - self.get_by_id(id).and_then(|t| match t.pure_state() { - State::Closed => None, - State::Done => Some(1.0), - _ => { - let count = t.children.len() as f32; - Some( - t.children - .iter() - .filter_map(|e| self.total_progress(e).map(|p| p / count)) - .sum(), - ) + self.tasks.get(id).map(|t| { + let state = t.pure_state(); + let mut prog = TaskProgress::from(&state); + if state.is_open() { + prog = prog + t.children + .iter() + .filter_map(|e| self.total_progress(e)) + .sum() } + prog }) } @@ -486,6 +484,45 @@ impl<'a> Iterator for ParentIterator<'a> { } } +#[derive(Default, Copy, Clone)] +struct TaskProgress { + total: usize, + done: usize, +} +impl TaskProgress { + fn fraction(&self) -> f32 { + (self.done as f32) / (self.total as f32) + } +} +impl From<&State> for TaskProgress { + fn from(value: &State) -> Self { + TaskProgress { + total: (value != &State::Closed).into(), + done: (value == &State::Done).into(), + } + } +} +impl Display for TaskProgress { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}/{}", self.done, self.total,) + } +} +impl Add for TaskProgress { + type Output = TaskProgress; + + fn add(self, rhs: Self) -> Self::Output { + TaskProgress { + done: self.done + rhs.done, + total: self.total + rhs.total, + } + } +} +impl Sum for TaskProgress { + fn sum>(iter: I) -> Self { + iter.fold(TaskProgress::default(), |acc, val| acc + val) + } +} + #[test] fn test_depth() { use std::sync::mpsc;