mod default;

/// Tracks current and previous values for rollback support.
#[derive(Debug, Clone)]
pub struct WithPrev<T> {
    pub(super) current: T,
    pub(super) previous: T,
}

impl<T> WithPrev<T> {
    pub fn new(value: T) -> Self
    where
        T: Clone,
    {
        Self {
            current: value.clone(),
            previous: value,
        }
    }

    #[inline(always)]
    pub fn current(&self) -> &T {
        &self.current
    }

    #[inline]
    pub fn current_mut(&mut self) -> &mut T {
        &mut self.current
    }

    #[inline(always)]
    pub fn previous(&self) -> &T {
        &self.previous
    }

    #[inline]
    pub fn previous_mut(&mut self) -> &mut T {
        &mut self.previous
    }

    /// Copies current into previous.
    #[inline]
    pub fn save(&mut self)
    where
        T: Clone,
    {
        self.previous.clone_from(&self.current);
    }

    /// Copies previous into current.
    #[inline]
    pub fn restore(&mut self)
    where
        T: Clone,
    {
        self.current.clone_from(&self.previous);
    }

    #[inline]
    pub fn swap(&mut self) {
        std::mem::swap(&mut self.current, &mut self.previous);
    }

    #[inline]
    pub fn take_current(&mut self) -> T
    where
        T: Default,
    {
        std::mem::take(&mut self.current)
    }

    #[inline]
    pub fn take_previous(&mut self) -> T
    where
        T: Default,
    {
        std::mem::take(&mut self.previous)
    }

    #[inline]
    pub fn clear(&mut self)
    where
        T: Default,
    {
        self.current = T::default();
        self.previous = T::default();
    }

    #[inline]
    pub fn clear_previous(&mut self)
    where
        T: Default,
    {
        self.previous = T::default();
    }
}
