progress_monitor/work/
set.rs

1use std::{
2    collections::BTreeSet,
3    fmt::{Debug, Display},
4    ops::{Add, Sub},
5};
6
7use crate::work::{AddError, Work};
8
9pub trait SetReq: Debug + PartialEq + Eq + PartialOrd + Ord + Clone + Copy {}
10
11impl<T: Debug + PartialEq + Eq + PartialOrd + Ord + Clone + Copy> SetReq for T {}
12
13#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
14pub struct SetWork<T: SetReq>(BTreeSet<T>);
15
16impl<T: SetReq> Display for SetWork<T> {
17    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18        f.write_fmt(format_args!("{:?}", self.0))
19    }
20}
21
22impl<T: SetReq> From<SetWork<T>> for f64 {
23    fn from(val: SetWork<T>) -> Self {
24        val.0.len() as f64
25    }
26}
27
28impl<T: SetReq> From<T> for SetWork<T> {
29    fn from(value: T) -> Self {
30        let mut set = BTreeSet::new();
31        set.insert(value);
32        Self(set)
33    }
34}
35
36impl<T: SetReq, const N: usize> From<&[T; N]> for SetWork<T> {
37    fn from(value: &[T; N]) -> Self {
38        let mut set = BTreeSet::new();
39        for v in value {
40            set.insert(*v);
41        }
42        Self(set)
43    }
44}
45
46impl<T: SetReq> Work for SetWork<T> {
47    type Type = BTreeSet<T>;
48
49    fn new<A: Into<Self::Type>>(value: A) -> Self {
50        SetWork(value.into())
51    }
52
53    fn zero() -> Self {
54        SetWork(BTreeSet::new())
55    }
56
57    fn min<'a>(a: &'a Self, b: &'a Self) -> &'a Self {
58        if a.0.len() < b.0.len() {
59            a
60        } else {
61            b
62        }
63    }
64
65    fn parent_work_done_when(
66        sub_work_done: Self,
67        _of_total_sub_work: Self,
68        of_parent_work: Self,
69    ) -> Self {
70        let mut partial = Self::zero();
71        for elem in sub_work_done.0.iter() {
72            if !of_parent_work.0.contains(elem) {
73                let _inserted = partial.0.insert(elem.clone());
74            }
75        }
76        partial
77    }
78}
79
80impl<T: SetReq> Add for SetWork<T> {
81    type Output = Result<Self, AddError>;
82
83    fn add(mut self, mut rhs: Self) -> Self::Output {
84        self.0.append(&mut rhs.0);
85
86        for r in rhs.0 {
87            if self.0.contains(&r) {
88                return Err(AddError {
89                    msg: format!("Element {r:?} is already present."),
90                });
91            }
92        }
93
94        Ok(SetWork(self.0))
95    }
96}
97
98impl<T: SetReq> Sub for SetWork<T> {
99    type Output = Self;
100
101    fn sub(self, rhs: Self) -> Self::Output {
102        let diff = self.0.difference(&rhs.0).map(|it| *it).collect();
103        SetWork(diff)
104    }
105}