Skip to main content

hexga_utils/
dirty.rs

1use super::*;
2
3pub mod prelude
4{
5    pub use super::{Dirty, DirtyFlag};
6}
7
8pub trait Dirty
9{
10    fn is_dirty(&self) -> bool;
11    fn set_dirty(&mut self, used: bool) -> &mut Self;
12    fn mark_dirty(&mut self) -> &mut Self { self.set_dirty(true) }
13    fn clear_dirty(&mut self) -> &mut Self { self.set_dirty(false) }
14}
15
16/// Mark value as dirty when mutated (using [`DerefMut`])
17#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
18pub struct DirtyFlag<T>
19{
20    value: T,
21    used: bool,
22}
23impl<T> From<T> for DirtyFlag<T>
24{
25    fn from(value: T) -> Self { Self::new(value) }
26}
27impl<T> DirtyFlag<T>
28{
29    pub fn new(value: T) -> Self { Self::with_used(value, false) }
30    pub fn with_used(value: T, used: bool) -> Self { Self { value, used } }
31
32    pub fn into_value(self) -> T { self.value }
33    pub fn into_value_and_used(self) -> (T, bool) { (self.value, self.used) }
34}
35impl<T> Deref for DirtyFlag<T>
36{
37    type Target = T;
38    fn deref(&self) -> &Self::Target { &self.value }
39}
40impl<T> DerefMut for DirtyFlag<T>
41{
42    fn deref_mut(&mut self) -> &mut Self::Target
43    {
44        self.mark_dirty();
45        &mut self.value
46    }
47}
48impl<T> Dirty for DirtyFlag<T>
49{
50    fn is_dirty(&self) -> bool { self.used }
51    fn set_dirty(&mut self, used: bool) -> &mut Self
52    {
53        self.used = used;
54        self
55    }
56}
57
58// Todo: DirtyHash, DirtyCounter...