scsys_core/state/nstate/
kind.rs

1/*
2    Appellation: kind <module>
3    Contrib: @FL03
4*/
5use super::NState;
6
7/// a private, base represenation of a state kind
8pub trait RawStateKind {
9    private!();
10}
11///
12///
13/// **note:** this trait is auto implemented for types that implement [`AsRef<str>`].
14pub trait StateKind: RawStateKind {
15    fn kind(&self) -> &str;
16}
17/// a particular kind of state that is defined by some _rank_
18pub trait NStateKind: StateKind {
19    /// the "rank" of the state speaks to the total number of dimensions (or states) allowed
20    const RANK: usize;
21}
22
23#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
24pub enum Nary<const N: usize> {}
25impl<T> RawStateKind for T
26where
27    T: AsRef<str>,
28{
29    seal!();
30}
31
32impl<T> StateKind for T
33where
34    T: AsRef<str>,
35{
36    fn kind(&self) -> &str {
37        self.as_ref()
38    }
39}
40
41macro_rules! impl_state_kind {
42    (@kind $n:literal) => {
43        paste::paste! {
44            #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
45            #[cfg_attr(feature = "serde", derive(serde_derive::Deserialize, serde_derive::Serialize))]
46            pub enum [<State $n>] {}
47
48            impl RawStateKind for [<State $n>] {
49                seal!();
50            }
51
52            impl StateKind for [<State $n>] {
53                fn kind(&self) -> &str {
54                    stringify!([<State $n>])
55                }
56            }
57
58            impl NStateKind for [<State $n>] {
59                const RANK: usize = $n;
60            }
61        }
62    };
63    (@state $name:ident($n:literal)) => {
64        paste::paste! {
65            pub type [<$name State>]<T> = NState<[<State $n>], T>;
66        }
67    };
68    ($($name:ident($n:literal)),* $(,)?) => {
69        $(
70            impl_state_kind!(@kind $n);
71            impl_state_kind!(@state $name($n));
72        )*
73    };
74}
75
76impl_state_kind! {
77    Unary(1),
78    Binary(2),
79    Ternary(3),
80    Quaternary(4),
81    Quinary(5),
82    Senary(6),
83    Septenary(7),
84    Octonary(8),
85    Nonary(9),
86    Denary(10),
87}