eryon_core/state/
state.rs

1/*
2    Appellation: state <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use super::Halt;
6
7/// [State] is a generalized state implementation, representing the state of a system or
8/// object.
9#[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(
11    feature = "serde",
12    derive(serde::Deserialize, serde::Serialize),
13    serde(transparent)
14)]
15#[repr(transparent)]
16pub struct State<Q: ?Sized = bool>(pub Q);
17
18impl<Q> State<Q> {
19    /// a constructor method for the [`State`] type.
20    pub const fn new(state: Q) -> Self {
21        Self(state)
22    }
23    /// initializes a new instance of state using the given initializer function.
24    pub fn create<F>(f: F) -> Self
25    where
26        F: FnOnce() -> Q,
27    {
28        State(f())
29    }
30    /// returns a new state with a value of one.
31    pub fn one() -> Self
32    where
33        Q: num_traits::One,
34    {
35        State::create(Q::one)
36    }
37    /// returns a new state with a value of zero.
38    pub fn zero() -> Self
39    where
40        Q: num_traits::Zero,
41    {
42        State::create(Q::zero)
43    }
44    /// returns a new instance of state with a raw pointer to the inner value.
45    pub const fn as_ptr(&self) -> *const Q {
46        core::ptr::addr_of!(self.0)
47    }
48    /// returns a new instance of state with a mutable raw pointer to the inner value.
49    pub const fn as_mut_ptr(&mut self) -> *mut Q {
50        core::ptr::addr_of_mut!(self.0)
51    }
52    #[allow(clippy::missing_safety_doc)]
53    /// Casts the state to a new type, returning a new instance of [State].
54    ///
55    /// # Saftey
56    ///
57    /// This method is unsafe because it is up to the caller to ensure that the cast is valid.
58    pub unsafe fn cast<R>(self) -> State<R> {
59        unsafe { State(core::ptr::read(&self.0 as *const Q as *const R)) }
60    }
61    /// returns an immutable reference to the inner value of the state.
62    pub const fn get(&self) -> &Q {
63        &self.0
64    }
65    /// returns a mutable reference to the inner value of the state.
66    pub const fn get_mut(&mut self) -> &mut Q {
67        &mut self.0
68    }
69    /// consumes and returns the inner value of the state.
70    #[inline]
71    pub fn value(self) -> Q {
72        self.0
73    }
74    /// [State::map] applies the given function onto the inner value of the state, returning a
75    /// new state with the result.
76    pub fn map<R, F>(self, f: F) -> State<R>
77    where
78        F: FnOnce(Q) -> R,
79    {
80        State(f(self.value()))
81    }
82    /// [`replace`](core::mem::replace) the inner value of the state with the given state,
83    pub const fn replace(&mut self, state: Q) -> Q {
84        core::mem::replace(self.get_mut(), state)
85    }
86    /// Clears the state, setting it to its default value.
87    #[inline]
88    pub fn reset(&mut self) -> &mut Self
89    where
90        Q: Default,
91    {
92        self.set(Default::default());
93        self
94    }
95    /// Sets the state to a new value.
96    pub fn set(&mut self, state: Q) -> &mut Self {
97        self.0 = state;
98        self
99    }
100    /// [`swap`](core::mem::swap) the inner value of the state with that of the given state.
101    pub const fn swap(&mut self, other: &mut State<Q>) {
102        core::mem::swap(self.get_mut(), other.get_mut());
103    }
104    /// [`take`](core::mem::take) the inner value of the state, leaving the logical default in
105    /// its place
106    pub fn take(&mut self) -> Q
107    where
108        Q: Default,
109    {
110        core::mem::take(self.get_mut())
111    }
112    /// returns a halted state with an immutable reference to the state.
113    pub fn as_halt(&self) -> State<Halt<&Q>> {
114        State::new(Halt(self))
115    }
116    /// Consumes the state and returns a halted state.
117    pub fn into_halt(self) -> State<Halt<Q>> {
118        State::new(Halt(self.value()))
119    }
120    /// Wraps the inner value with a [Halt] state, returning a new instance of [State].
121    pub fn halt(self) -> State<Halt<Q>> {
122        State::new(Halt(self.value()))
123    }
124    /// returns `true` if the state is a [Halt] state.
125    pub fn is_halt(&self) -> bool
126    where
127        Q: 'static,
128    {
129        core::any::TypeId::of::<Self>() == core::any::TypeId::of::<State<Halt<Q>>>()
130    }
131    /// returns a new state with a boxed inner value.
132    pub fn boxed(self) -> State<Box<Q>> {
133        self.map(Box::new)
134    }
135    /// Converts the inner type into a boxed "any" state, returning a new instance of state
136    pub fn as_any(&self) -> State<Box<dyn std::any::Any>>
137    where
138        Q: Clone + 'static,
139    {
140        State(Box::new(self.get().clone()))
141    }
142    /// Converts the inner type into a boxed "any" state, returning a new instance of state
143    pub fn into_any(self) -> State<Box<dyn std::any::Any>>
144    where
145        Q: 'static,
146    {
147        State(Box::new(self.value()))
148    }
149
150    #[cfg(feature = "std")]
151    /// Wraps the inner value of the state with an [`Arc`] and returns a new instance of [State]
152    pub fn shared(self) -> State<std::sync::Arc<Q>> {
153        self.map(std::sync::Arc::new)
154    }
155    #[cfg(feature = "std")]
156    /// returns a shared reference to the state.
157    pub fn to_shared(&self) -> State<std::sync::Arc<Q>>
158    where
159        Q: Clone,
160    {
161        self.clone().shared()
162    }
163    /// returns a state with an owned inner value.
164    pub const fn view(&self) -> State<&Q> {
165        State(self.get())
166    }
167    /// returns a state with a mutable reference to the inner value.
168    pub const fn view_mut(&mut self) -> State<&mut Q> {
169        State(self.get_mut())
170    }
171    /// returns the `name` of the generic inner type, `Q`.
172    pub fn get_inner_type_name(&self) -> &'static str {
173        core::any::type_name::<Q>()
174    }
175    /// returns the `type id` of the generic inner type, `Q`.
176    pub fn get_inner_type_id(&self) -> core::any::TypeId
177    where
178        Q: 'static,
179    {
180        core::any::TypeId::of::<Q>()
181    }
182}
183
184impl<Q> State<Q> {
185    #[deprecated(
186        since = "0.0.7",
187        note = "use `value` instead, as it is more idiomatic and clearer."
188    )]
189    pub fn into_inner(self) -> Q {
190        self.0
191    }
192    #[deprecated(
193        since = "0.0.7",
194        note = "use `view` instead, as it is more idiomatic and clearer."
195    )]
196    pub fn to_ref(&self) -> State<&Q> {
197        self.view()
198    }
199    #[deprecated(
200        since = "0.0.7",
201        note = "use `view_mut` instead, as it is more idiomatic and clearer."
202    )]
203    pub fn to_mut(&mut self) -> State<&mut Q> {
204        self.view_mut()
205    }
206}