rs_mois_dirty/
lib.rs

1pub struct Dirty<T> {
2    dirty: bool,
3    value: T,
4}
5
6impl<T: Default> Default for Dirty<T> {
7    fn default() -> Self { Self{dirty: false, value: Default::default() } }
8}
9
10impl<T: PartialEq> PartialEq for Dirty<T> {
11    fn eq(&self, other: &Self) -> bool {
12        (self.dirty == other.dirty) && (self.value == other.value)
13    }
14
15    fn ne(&self, other: &Self) -> bool {
16        (self.dirty != other.dirty) || (self.value != self.value)
17    }
18}
19
20impl<T> Dirty<T> {
21    pub fn update_if_dirty<F>(&mut self, f: F) -> &T
22        where F:FnOnce() -> T{
23        if !self.dirty {
24            &self.value
25        } else {
26            self.dirty = false;
27            self.value = f();
28            &self.value
29        }
30    }
31
32    pub fn set_dirty(&mut self) {
33        self.dirty = true;
34    }
35
36    pub fn clear_dirty(&mut self) {
37        self.dirty = false;
38    }
39
40    pub fn update(&mut self, v: T) {
41        self.dirty = true;
42        self.value = v;
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn dirty_default() {
52        let d: Dirty<usize> = Default::default();
53        assert_eq!(d.dirty, false);
54        assert_eq!(d.value, 0);
55    }
56
57    #[test]
58    fn dirty_update() {
59        let mut d: Dirty<usize> = Default::default();
60        d.update(15);
61        assert_eq!(d.dirty, true);
62        assert_eq!(d.value, 15);
63    }
64
65    #[test]
66    fn dirty_update_if_dirty() {
67        let mut d: Dirty<usize> = Default::default();
68        d.update_if_dirty(|| 9);
69        assert_eq!(d.dirty, false);
70        assert_eq!(d.value, 0);
71
72        d.update(7);
73        d.update_if_dirty(|| 20);
74        assert_eq!(d.dirty, false);
75        assert_eq!(d.value, 20);
76    }
77
78    #[test]
79    fn dirty_set_dirty() {
80        let mut d: Dirty<usize> = Default::default();
81        d.set_dirty();
82        assert_eq!(d.dirty, true);
83    }
84
85    #[test]
86    fn dirty_clear_dirty () {
87        let mut d: Dirty<usize> = Default::default();
88        d.update(8);
89        d.clear_dirty();
90        assert_eq!(d.dirty, false);
91    }
92
93}