#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[cfg(test)]
mod tests;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone)]
pub struct Reversible<T: Default + Debug + Clone> {
#[cfg_attr(feature = "serde", serde(flatten))]
data: T,
#[cfg_attr(feature = "serde", serde(skip))]
edit: Option<T>,
}
impl<T: Default + Debug + Clone> AsRef<T> for Reversible<T> {
fn as_ref(&self) -> &T {
&self.data
}
}
impl<T: Default + Debug + Clone> AsMut<T> for Reversible<T> {
fn as_mut(&mut self) -> &mut T {
if self.edit.is_none() {
self.force_edit();
}
self.edit.as_mut().expect("self.edit is always Some")
}
}
impl<T: Default + Debug + Clone> std::fmt::Debug for Reversible<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.as_ref())
}
}
impl<T: Default + Debug + Clone> Default for Reversible<T> {
fn default() -> Self {
Reversible {
data: T::default(),
edit: None,
}
}
}
impl<T: Default + Debug + Clone> From<T> for Reversible<T> {
fn from(value: T) -> Self {
Reversible::new(value)
}
}
impl<T: Default + Debug + Clone> Reversible<T> {
pub fn new(data: T) -> Self {
Reversible { data, edit: None }
}
pub fn as_ref_edit(&self) -> &T {
match &self.edit {
Some(edit) => edit,
None => &self.data,
}
}
pub fn save(&mut self) {
if let Some(edit) = self.edit.take() {
self.data = edit;
}
}
pub fn revert(&mut self) {
self.edit = None;
}
pub fn is_edit(&self) -> bool {
self.edit.is_some()
}
pub fn force_edit(&mut self) {
self.edit = Some(self.data.clone());
}
}