#![doc = include_str!("../README.md")]
use std::ops::{Deref, DerefMut};
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Dirty<T> {
pub data: T,
pub dirty: bool,
}
impl<T> Dirty<T> {
pub fn new(data: T) -> Self {
Self { data, dirty: false }
}
pub fn clean(&mut self, mut f: impl FnMut(&mut T)) {
if self.dirty {
self.dirty = false;
f(&mut self.data);
}
}
pub fn as_dirty(&self) -> Option<&T> {
if self.dirty {
Some(&self.data)
} else {
None
}
}
pub fn as_clean(&self) -> Option<&T> {
if self.dirty {
None
} else {
Some(&self.data)
}
}
pub fn as_dirty_mut(&mut self) -> Option<&mut T> {
if self.dirty {
Some(&mut self.data)
} else {
None
}
}
pub fn as_clean_mut(&mut self) -> Option<&mut T> {
if self.dirty {
None
} else {
Some(&mut self.data)
}
}
}
impl<T> AsRef<T> for Dirty<T> {
fn as_ref(&self) -> &T {
self.deref()
}
}
impl<T> AsMut<T> for Dirty<T> {
fn as_mut(&mut self) -> &mut T {
self.deref_mut()
}
}
impl<T: Default> Default for Dirty<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> Deref for Dirty<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<T> DerefMut for Dirty<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.dirty = true;
&mut self.data
}
}
impl<T> From<T> for Dirty<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}