use core::clone::Clone;
use std::ops::{Deref, DerefMut};
use crate::Mutable;
pub struct MutableHolder<M: Mutable + Clone> {
old: M,
current: M,
mutations: Vec<M::Mutation>,
}
impl<M: Mutable + Clone> MutableHolder<M> {
pub fn new(value: M) -> MutableHolder<M> {
MutableHolder{
old: value.clone(),
current: value,
mutations: vec![]
}
}
pub fn get(&self) -> &M { &self.current }
pub fn get_mut(&mut self) -> MHRefMut<M> { MHRefMut(self) }
pub(crate) fn collect_mutations(&mut self) {
self.mutations.append(&mut self.old.update(self.current.clone()))
}
pub fn mutations(&mut self) -> Vec<M::Mutation> {
let mutations = self.mutations.clone();
self.mutations.clear();
mutations
}
}
pub struct MHRefMut<'r, M: Mutable + Clone>(&'r mut MutableHolder<M>);
impl<'r, M: Mutable + Clone> Deref for MHRefMut<'r, M> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.0.current
}
}
impl<'r, M: Mutable + Clone> DerefMut for MHRefMut<'r, M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0.current
}
}
impl<'r, M: Mutable + Clone> Drop for MHRefMut<'r, M> {
fn drop(&mut self) {
self.0.collect_mutations();
}
}