scsys_core/state/
wrapper.rs

1/*
2    appellation: wrapper <module>
3    authors: @FL03
4*/
5use super::RawState;
6
7/// [`State`] is generic over some type `Q` that implements the [`RawState`] trait.
8#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
9#[cfg_attr(
10    feature = "serde",
11    derive(serde::Deserialize, serde::Serialize),
12    serde(default, transparent)
13)]
14#[repr(transparent)]
15pub struct State<Q = usize>(pub Q);
16
17/// generic implementation of the [`State`] type available for all types `Q`
18impl<Q> State<Q>
19where
20    Q: RawState,
21{
22    /// returns a new instance of [`State`] with the given value
23    pub const fn new(state: Q) -> Self {
24        State(state)
25    }
26    /// returns a new instance of [`State`] using the output of the given function `F`
27    pub fn new_with<F>(f: F) -> Self
28    where
29        F: FnOnce() -> Q,
30    {
31        Self::new(f())
32    }
33    #[allow(clippy::should_implement_trait)]
34    /// returns a new instance of [`State`] using the logical default for the type `Q`
35    pub fn default() -> Self
36    where
37        Q: Default,
38    {
39        State(Q::default())
40    }
41    /// returns a new instance of [`State`] with an inner value of `1`
42    pub fn one() -> Self
43    where
44        Q: num_traits::One,
45    {
46        State(Q::one())
47    }
48    /// returns a new instance of [`State`] with an inner value of `0`
49    pub fn zero() -> Self
50    where
51        Q: num_traits::Zero,
52    {
53        State(Q::zero())
54    }
55    /// generate a new instance of the state with a random value
56    #[cfg(feature = "rand")]
57    pub fn random() -> Self
58    where
59        rand_distr::StandardUniform: rand_distr::Distribution<Q>,
60    {
61        use rand::Rng;
62        let mut rng = rand::rng();
63        Self::new(rng.random())
64    }
65    #[cfg(feature = "rand")]
66    pub fn random_with<R, Dist>(rng: &mut R, distr: Dist) -> Self
67    where
68        Dist: rand_distr::Distribution<Q>,
69        R: rand::RngCore,
70    {
71        use rand::Rng;
72        // sample a value using the given rng configured with the given distribution
73        let value = rng.sample(distr);
74        // return a new instance of the state with the sampled value
75        State(value)
76    }
77    /// returns an immutable reference to the inner value
78    pub const fn get(&self) -> &Q {
79        &self.0
80    }
81    /// returns a mutable reference to the inner value
82    pub const fn get_mut(&mut self) -> &mut Q {
83        &mut self.0
84    }
85    /// consumes the current instance to return the inner value
86    #[inline]
87    pub fn value(self) -> Q {
88        self.0
89    }
90    /// [`replace`](core::mem::replace) the inner state with the given value and return the
91    /// previous
92    pub const fn replace(&mut self, state: Q) -> Q {
93        core::mem::replace(self.get_mut(), state)
94    }
95    /// mutate the inner value and return a mutable reference to the wrapper for chaining
96    pub fn set(&mut self, state: Q) -> &mut Self {
97        *self.get_mut() = state;
98        self
99    }
100    /// [`swap`](core::mem::swap) the inner value with that of another state instance of the
101    /// same type `Q`
102    pub const fn swap(&mut self, state: &mut State<Q>) {
103        core::mem::swap(self.get_mut(), state.get_mut())
104    }
105    /// takes the inner value and replaces it with the default value
106    pub fn take(&mut self) -> Q
107    where
108        Q: Default,
109    {
110        core::mem::take(self.get_mut())
111    }
112    /// consumes the current instance to replace it with another.
113    pub fn with<U>(self, id: U) -> State<U> {
114        State(id)
115    }
116    /// apply a function onto the inner value and return a new instance with the result
117    pub fn map<U, F>(self, f: F) -> State<U>
118    where
119        F: FnOnce(Q) -> U,
120    {
121        State(f(self.0))
122    }
123    /// updates the inner value using the given function and returns a mutable reference to the
124    /// current instance for chaining
125    pub fn map_inplace<F>(&mut self, f: F) -> &mut Self
126    where
127        F: FnOnce(&mut Q),
128    {
129        f(self.get_mut());
130        self
131    }
132    /// returns a new instance containing a reference to the inner value
133    pub const fn view(&self) -> State<&Q> {
134        State(self.get())
135    }
136    /// returns a new instance containing a mutable reference to the inner value
137    pub const fn view_mut(&mut self) -> State<&mut Q> {
138        State(self.get_mut())
139    }
140}
141
142#[allow(deprecated)]
143impl<Q> State<Q>
144where
145    Q: RawState,
146{
147    #[deprecated(
148        since = "0.2.9",
149        note = "use `value` instead, this will be removed in the next major release"
150    )]
151    pub fn into_inner(self) -> Q {
152        self.0
153    }
154}