ownables 0.1.1

A library that defines the Ownable trait and facilitates mutation by moving or reading from the source.
Documentation
//! # Ownables
//!
//! A library that defines the Ownable trait and facilitates mutation by moving or reading from the source.

pub use guard::TakenGuard;

mod guard;

/// Defines the core structure of a Container that holds a value which can be moved out and returned to it
/// Allowing mutation by moving and returning, or simply reading directly from it.
pub trait Ownable {
    type Item;
    fn take(&mut self) -> TakenGuard<Self, Self::Item>
    where
        Self: Sized;
    fn read(&self) -> Option<&Self::Item>;
    fn put_back(&mut self, val: Self::Item);
    fn is_available(&self) -> bool;
}

/// A simple container implementation of Ownable, holds the item in the Available variant.
pub enum OwnableCell<T> {
    Available(T),
    Taken,
}
/// Defines a Cell that holds a number, takes and mutates it and then reads from the Cell again.
///
/// # Examples
/// ```
/// let mut source = OwnableCell::Available(100);
/// {
///     let mut guard = item.take();
///     *guard.unwrap() += 100;
/// }
/// assert_eq!(200, source.read().unwrap());
///```
impl<T> Ownable for OwnableCell<T> {
    type Item = T;
    fn take(&mut self) -> TakenGuard<Self, Self::Item> {
        match std::mem::replace(self, Self::Taken) {
            Self::Available(v) => TakenGuard::new(self, Some(v)),
            Self::Taken => TakenGuard::new(self, None),
        }
    }

    fn read(&self) -> Option<&Self::Item> {
        let Self::Available(v) = self else {
            return None;
        };
        Some(&v)
    }

    fn put_back(&mut self, val: Self::Item) {
        *self = Self::Available(val);
    }

    fn is_available(&self) -> bool {
        matches!(self, Self::Available(_))
    }
}