Skip to main content

reversible/
lib.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use std::fmt::Debug;
4
5#[cfg(test)]
6mod tests;
7
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9#[derive(Clone)]
10pub struct Reversible<T: Default + Debug + Clone> {
11    #[cfg_attr(feature = "serde", serde(flatten))]
12    data: T,
13    #[cfg_attr(feature = "serde", serde(skip))]
14    edit: Option<T>,
15}
16impl<T: Default + Debug + Clone> AsRef<T> for Reversible<T> {
17    fn as_ref(&self) -> &T {
18        &self.data
19    }
20}
21impl<T: Default + Debug + Clone> AsMut<T> for Reversible<T> {
22    fn as_mut(&mut self) -> &mut T {
23        if self.edit.is_none() {
24            self.force_edit();
25        }
26        self.edit.as_mut().expect("self.edit is always Some")
27    }
28}
29impl<T: Default + Debug + Clone> std::fmt::Debug for Reversible<T> {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        write!(f, "{:?}", self.as_ref())
32    }
33}
34impl<T: Default + Debug + Clone> Default for Reversible<T> {
35    fn default() -> Self {
36        Reversible {
37            data: T::default(),
38            edit: None,
39        }
40    }
41}
42impl<T: Default + Debug + Clone> From<T> for Reversible<T> {
43    fn from(value: T) -> Self {
44        Reversible::new(value)
45    }
46}
47
48impl<T: Default + Debug + Clone> Reversible<T> {
49    pub fn new(data: T) -> Self {
50        Reversible { data, edit: None }
51    }
52    /// Reference to Edited Value
53    pub fn as_ref_edit(&self) -> &T {
54        match &self.edit {
55            Some(edit) => edit,
56            None => &self.data,
57        }
58    }
59
60    /// Mutable reference to Data for some cases
61    pub fn as_mut_data(&mut self) -> &mut T {
62        &mut self.data
63    }
64
65    /// Save Edited Value
66    /// # Example
67    /// ```
68    /// let mut rev = reversible::Reversible::new(4);
69    /// *rev.as_mut() = 13;
70    /// assert_eq!(rev.as_ref(), &4);
71    /// assert_eq!(rev.as_mut(), &mut 13);
72    /// rev.save();
73    /// assert_eq!(rev.as_ref(), &13);
74    /// assert_eq!(rev.as_ref(), rev.as_ref_edit());
75    /// ```
76    pub fn save(&mut self) {
77        if let Some(edit) = self.edit.take() {
78            self.data = edit;
79        }
80    }
81
82    /// Revert Edited Value
83    /// # Example
84    /// ```
85    /// let mut rev = reversible::Reversible::new(4);
86    /// *rev.as_mut() = 13;
87    /// assert_eq!(rev.as_ref(), &4);
88    /// assert_eq!(rev.as_mut(), &mut 13);
89    /// rev.revert();
90    /// assert_eq!(rev.as_mut(), &mut 4);
91    /// assert_eq!(rev.as_ref(), rev.as_ref_edit());
92    /// ```
93    pub fn revert(&mut self) {
94        self.edit = None;
95    }
96
97    /// Does it have Edited Value
98    /// # Example
99    /// ```
100    /// let mut rev = reversible::Reversible::new(4);
101    /// assert_eq!(rev.is_edit(), false);
102    /// *rev.as_mut() = 13;
103    /// assert!(rev.is_edit());
104    /// ```
105    pub fn is_edit(&self) -> bool {
106        self.edit.is_some()
107    }
108
109    /// Force to have Edited Value same as Saved Value
110    /// # Example
111    /// ```
112    /// let mut rev = reversible::Reversible::new(4);
113    /// assert_eq!(rev.is_edit(), false);
114    /// rev.force_edit();
115    /// assert!(rev.is_edit());
116    /// ```
117    pub fn force_edit(&mut self) {
118        self.edit = Some(self.data.clone());
119    }
120}