eryon-mem 0.0.4

this crate implements the memory-related aspects of the eryon framework
/*
    appellation: position <module>
    authors: @FL03
*/

/// [`MemoryPosition`] tracks the current indices for various aspects of the memory system to
/// ensure consistency when allocating new features or patterns.
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(
    feature = "serde",
    derive(serde_derive::Deserialize, serde_derive::Serialize),
    serde(default, rename_all = "snake_case")
)]
pub struct MemoryPosition<T = usize> {
    /// Next feature ID
    pub(crate) feature_id: T,
    /// Next pattern ID
    pub(crate) pattern_id: T,
}

impl<T> MemoryPosition<T> {
    /// returns a new instance of [`MemoryPosition`] using the provided `feature_id` and
    /// `pattern_id`.
    pub fn new(feature_id: T, pattern_id: T) -> Self {
        Self {
            feature_id,
            pattern_id,
        }
    }
    /// initializes a new instance using the logical [`Default`] for type `T`.
    pub fn default() -> Self
    where
        T: Default,
    {
        MemoryPosition {
            feature_id: Default::default(),
            pattern_id: Default::default(),
        }
    }
    /// initialize a new instance using [`num_traits::One`]
    pub fn one() -> Self
    where
        T: num_traits::One,
    {
        MemoryPosition {
            feature_id: T::one(),
            pattern_id: T::one(),
        }
    }
    /// initialize a new instance using [`num_traits::Zero`]
    pub fn zero() -> Self
    where
        T: num_traits::Zero,
    {
        MemoryPosition {
            feature_id: T::zero(),
            pattern_id: T::zero(),
        }
    }
    /// creates a new instance of [`MemoryPosition`] from a given `feature_id` and a default
    /// `pattern_id`.
    pub fn from_feature_id(feature_id: T) -> Self
    where
        T: Default,
    {
        MemoryPosition {
            feature_id,
            pattern_id: T::default(),
        }
    }
    /// creates a new instance of [`MemoryPosition`] from a given `pattern_id` and a default
    /// `feature_id`.
    pub fn from_pattern_id(pattern_id: T) -> Self
    where
        T: Default,
    {
        MemoryPosition {
            feature_id: T::default(),
            pattern_id,
        }
    }
    /// returns an immutable reference to the current feature id
    pub const fn feature_id(&self) -> &T {
        &self.feature_id
    }
    /// returns a mutable reference to the current feature id
    pub const fn feature_id_mut(&mut self) -> &mut T {
        &mut self.feature_id
    }
    /// returns an immutable reference to the current pattern id
    pub const fn pattern_id(&self) -> &T {
        &self.pattern_id
    }
    /// returns a mutable reference to the current pattern id
    pub const fn pattern_id_mut(&mut self) -> &mut T {
        &mut self.pattern_id
    }
    /// [`replace`](core::mem::replace) the current feature ID with the given `id` and return
    /// the old value.
    pub const fn replace_feature_id(&mut self, id: T) -> T {
        core::mem::replace(self.feature_id_mut(), id)
    }
    /// [`replace`](core::mem::replace) the current pattern ID with the given `id` and return
    /// the old value.
    pub const fn replace_pattern_id(&mut self, id: T) -> T {
        core::mem::replace(self.pattern_id_mut(), id)
    }
    /// returns the current feature id, replacing it with the logical successor
    pub fn next_feature_id(&mut self) -> T
    where
        T: num_traits::One,
        for<'a> &'a T: core::ops::Add<T, Output = T>,
    {
        self.replace_feature_id(self.feature_id() + T::one())
    }
    /// returns the current pattern id and replaces it with an incremented value
    pub fn next_pattern_id(&mut self) -> T
    where
        T: num_traits::One,
        for<'a> &'a T: core::ops::Add<T, Output = T>,
    {
        self.replace_pattern_id(self.pattern_id() + T::one())
    }
}

impl<T> core::fmt::Display for MemoryPosition<T>
where
    T: core::fmt::Display,
{
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(
            f,
            "{{ feature_id: {}, pattern_id: {} }}",
            self.feature_id, self.pattern_id
        )
    }
}