progress_monitor/work/
set.rs1use 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}