use core::{
cmp::Ordering,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
};
#[derive(Debug)]
pub struct Tracked<'a, T> {
value: &'a mut T,
changed: &'a mut bool,
}
impl<'a, T> Tracked<'a, T> {
pub(crate) fn new(value: &'a mut T, flag: &'a mut bool) -> Self {
Self {
value,
changed: flag,
}
}
#[must_use]
pub fn has_changed(&self) -> bool {
*self.changed
}
pub fn mark_changed(&mut self) {
*self.changed = true;
}
}
impl<T> Deref for Tracked<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<T> DerefMut for Tracked<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
*self.changed = true;
self.value
}
}
impl<T> AsRef<T> for Tracked<'_, T> {
fn as_ref(&self) -> &T {
self.value
}
}
impl<T> AsMut<T> for Tracked<'_, T> {
fn as_mut(&mut self) -> &mut T {
*self.changed = true;
self.value
}
}
impl<T: PartialEq> PartialEq for Tracked<'_, T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: Eq> Eq for Tracked<'_, T> {}
impl<T: PartialOrd> PartialOrd for Tracked<'_, T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.value.partial_cmp(&other.value)
}
}
impl<T: Ord> Ord for Tracked<'_, T> {
fn cmp(&self, other: &Self) -> Ordering {
self.value.cmp(&other.value)
}
}
impl<T: Hash> Hash for Tracked<'_, T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}