summary refs log tree commit diff
path: root/src/util/option_tracker.rs
blob: 3c19ee5dfbc8f0efafa06251e14a754072f543b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
pub struct OptionTracker<T> {
    inner: Option<T>,
    dirty: bool,
}

/// Tracks changes to an inner Option<T>. Any change using `set` will cause the
/// tracker to be marked as dirty, unless both the current and new value are
/// `None`. This should be used when changes from `Some(something)` to
/// `Some(something_different)` are rare, or when comparing inner values is more
/// expensive than performing an update which will mark the tracker as clean.
impl<T> OptionTracker<T> {
    pub fn new(inner: Option<T>) -> Self {
        Self { inner, dirty: true }
    }

    pub fn get(&self) -> &Option<T> {
        &self.inner
    }

    pub fn set(&mut self, value: Option<T>) {
        match (&self.inner, &value) {
            (None, None) => {}
            _ => self.dirty = true,
        }

        self.inner = value;
    }

    pub fn is_dirty(&self) -> bool {
        self.dirty
    }

    /// Marks the tracker as clean.
    pub fn reset(&mut self) {
        self.dirty = false;
    }
}

impl<T> Default for OptionTracker<T> {
    fn default() -> Self {
        Self::new(Option::default())
    }
}