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}