scsys_core/state/
nstate.rs

1/*
2    Appellation: state <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use core::marker::PhantomData;
6
7/// A type alias for a [Nary] state with a default value of 4.
8pub type NState<T, const N: usize = 4> = State<Nary<N>, T>;
9
10#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
11pub enum Nary<const N: usize> {}
12
13macro_rules! impl_state_kind {
14    (@kind $n:literal) => {
15        paste::paste! {
16            #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
17            #[cfg_attr(feature = "serde", derive(serde_derive::Deserialize, serde_derive::Serialize))]
18            pub enum [<State $n>] {}
19        }
20    };
21    (@state $name:ident($n:literal)) => {
22        paste::paste! {
23            pub type [<$name State>]<T> = State<[<State $n>], T>;
24        }
25    };
26    ($($name:ident($n:literal)),* $(,)?) => {
27        $(
28            impl_state_kind!(@kind $n);
29            impl_state_kind!(@state $name($n));
30        )*
31    };
32}
33
34impl_state_kind!(Unary(1), Binary(2), Ternary(3));
35
36/// [State] is an abstract object that allows a particular _kind_ of state to be associated
37/// with some data.
38#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
39#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
40pub struct State<K, V> {
41    pub(crate) data: V,
42    pub(crate) _state: PhantomData<K>,
43}
44
45impl<K, V> State<K, V> {
46    pub fn new(data: V) -> Self {
47        Self {
48            data,
49            _state: PhantomData::<K>,
50        }
51    }
52
53    pub fn data(&self) -> &V {
54        &self.data
55    }
56
57    pub fn is_state<R: 'static>(&self) -> bool
58    where
59        K: 'static,
60    {
61        use core::any::TypeId;
62        TypeId::of::<PhantomData<K>>() == TypeId::of::<PhantomData<R>>()
63    }
64}