Skip to main content

rstm_state/impls/
impl_state.rs

1/*
2    Appellation: impl_state <module>
3    Contrib: @FL03
4*/
5use crate::RawState;
6use crate::state::{Halt, State};
7
8impl<Q> State<Q> {
9    /// a constructor method for the [`State`] type.
10    pub const fn new(state: Q) -> Self {
11        Self(state)
12    }
13    /// create a new state by invoking the given function and capturing its output.
14    #[inline]
15    pub fn init<F>(f: F) -> Self
16    where
17        F: FnOnce() -> Q,
18    {
19        State(f())
20    }
21    /// returns a new state with a value of one.
22    pub fn one() -> Self
23    where
24        Q: num_traits::One,
25    {
26        State::init(Q::one)
27    }
28    /// returns a new state with a value of zero.
29    pub fn zero() -> Self
30    where
31        Q: num_traits::Zero,
32    {
33        State::init(Q::zero)
34    }
35    /// returns a new instance of state with a raw pointer to the inner value.
36    pub const fn as_ptr(&self) -> *const Q {
37        core::ptr::addr_of!(self.0)
38    }
39    /// returns a new instance of state with a mutable raw pointer to the inner value.
40    pub const fn as_mut_ptr(&mut self) -> *mut Q {
41        core::ptr::addr_of_mut!(self.0)
42    }
43    /// returns an immutable reference to the inner value of the state.
44    pub const fn get(&self) -> &Q {
45        &self.0
46    }
47    /// returns a mutable reference to the inner value of the state.
48    pub const fn get_mut(&mut self) -> &mut Q {
49        &mut self.0
50    }
51    /// consumes and returns the inner value of the state.
52    #[inline]
53    pub fn value(self) -> Q {
54        self.0
55    }
56    /// Casts the state to a new type, returning a new instance of [State].
57    ///
58    /// # Safety
59    ///
60    /// The method is marked unsafe because there are no guarantees that the inner type `Q`
61    /// can be safely interpreted as type `R`. The caller must ensure that the cast is valid
62    /// to avoid undefined behavior.
63    #[inline]
64    pub unsafe fn cast<R>(self) -> State<R> {
65        unsafe { State(core::ptr::read(&self.0 as *const Q as *const R)) }
66    }
67    /// [State::map] applies the given function onto the inner value of the state, returning a
68    /// new state with the result.
69    pub fn map<R, F>(self, f: F) -> State<R>
70    where
71        F: FnOnce(Q) -> R,
72    {
73        State(f(self.value()))
74    }
75    /// reset the state back to its logical default, returning the previous value.
76    pub fn reset(&mut self) -> State<Q>
77    where
78        Q: Default,
79    {
80        let prev = self.take();
81        State(prev)
82    }
83    /// update the current value of the object with the given state.
84    #[inline]
85    pub fn set(&mut self, state: Q) {
86        self.0 = state;
87    }
88    /// [`replace`](core::mem::replace) the inner value of the state with the given state,
89    pub const fn replace(&mut self, state: Q) -> Q {
90        core::mem::replace(self.get_mut(), state)
91    }
92    /// [`swap`](core::mem::swap) the inner value of the state with that of the given state.
93    pub const fn swap(&mut self, other: &mut State<Q>) {
94        core::mem::swap(self.get_mut(), other.get_mut());
95    }
96    /// [`take`](core::mem::take) the inner value of the state, leaving the logical default in
97    /// its place
98    pub fn take(&mut self) -> Q
99    where
100        Q: Default,
101    {
102        core::mem::take(self.get_mut())
103    }
104    /// converts the current reference into a haltable state initialized with the current state
105    pub fn as_halt(&self) -> State<Halt<&Q>>
106    where
107        Q: RawState,
108    {
109        State::new(Halt::Halt(self.get()))
110    }
111    /// consumes the wrapper to create another, haltable state that is initialized with the
112    /// current state
113    pub fn into_halt(self) -> State<Halt<Q>>
114    where
115        Q: RawState,
116    {
117        State::new(Halt::Step(self.value()))
118    }
119    /// consumes the current state, returning a new one with a [`Halt`](Halt::Halt)
120    /// variant initialized with the current value.
121    pub fn halt(self) -> State<Halt<Q>>
122    where
123        Q: RawState,
124    {
125        State::new(Halt::Halt(self.value()))
126    }
127    /// returns a state with an owned inner value.
128    pub const fn view(&self) -> State<&Q> {
129        State(self.get())
130    }
131    /// returns a state with a mutable reference to the inner value.
132    pub const fn view_mut(&mut self) -> State<&mut Q> {
133        State(self.get_mut())
134    }
135    /// returns the `name` of the generic inner type, `Q`.
136    pub fn get_inner_type_name(&self) -> &'static str {
137        core::any::type_name::<Q>()
138    }
139    /// returns the `type id` of the generic inner type, `Q`.
140    pub const fn get_inner_type_id(&self) -> core::any::TypeId
141    where
142        Q: 'static,
143    {
144        core::any::TypeId::of::<Q>()
145    }
146}
147
148#[cfg(feature = "alloc")]
149/// Additional implementations for the [`State`] type enabled whenever the `alloc` feature is
150/// toggled.
151impl<Q> State<Q> {
152    /// returns a new state with a boxed inner value.
153    pub fn boxed(self) -> State<alloc::boxed::Box<Q>> {
154        self.map(alloc::boxed::Box::new)
155    }
156    /// Converts the inner type into a boxed "any" state, returning a new instance of state
157    pub fn as_any(&self) -> State<alloc::boxed::Box<dyn core::any::Any>>
158    where
159        Q: Clone + 'static,
160    {
161        State(alloc::boxed::Box::new(self.get().clone()))
162    }
163    /// Converts the inner type into a boxed "any" state, returning a new instance of state
164    pub fn into_any(self) -> State<alloc::boxed::Box<dyn core::any::Any>>
165    where
166        Q: 'static,
167    {
168        State(alloc::boxed::Box::new(self.value()))
169    }
170    /// convert the state into another instance by wrapping the inner value with an [`Arc`](alloc::sync::Arc).
171    pub fn shared(self) -> State<alloc::sync::Arc<Q>> {
172        self.map(alloc::sync::Arc::new)
173    }
174    /// returns a shared reference to the state.
175    pub fn to_shared(&self) -> State<alloc::sync::Arc<Q>>
176    where
177        Q: Clone,
178    {
179        self.clone().shared()
180    }
181}
182
183impl<Q> AsRef<Q> for State<Q> {
184    fn as_ref(&self) -> &Q {
185        self.get()
186    }
187}
188
189impl<Q> AsMut<Q> for State<Q> {
190    fn as_mut(&mut self) -> &mut Q {
191        self.get_mut()
192    }
193}
194
195impl<Q> core::borrow::Borrow<Q> for State<Q> {
196    fn borrow(&self) -> &Q {
197        self.get()
198    }
199}
200
201impl<Q> core::borrow::BorrowMut<Q> for State<Q> {
202    fn borrow_mut(&mut self) -> &mut Q {
203        self.get_mut()
204    }
205}
206
207impl<Q> core::ops::Deref for State<Q> {
208    type Target = Q;
209
210    fn deref(&self) -> &Self::Target {
211        self.get()
212    }
213}
214
215impl<Q> core::ops::DerefMut for State<Q> {
216    fn deref_mut(&mut self) -> &mut Self::Target {
217        self.get_mut()
218    }
219}
220
221impl<Q> From<Q> for State<Q> {
222    fn from(state: Q) -> Self {
223        State(state)
224    }
225}
226
227impl<Q: PartialEq> PartialEq<Q> for State<Q> {
228    fn eq(&self, other: &Q) -> bool {
229        self.0.eq(other)
230    }
231}
232
233impl<'a, Q: PartialEq> PartialEq<&'a Q> for State<Q> {
234    fn eq(&self, other: &&'a Q) -> bool {
235        self.0.eq(*other)
236    }
237}
238
239impl<'a, Q: PartialEq> PartialEq<&'a mut Q> for State<Q> {
240    fn eq(&self, other: &&'a mut Q) -> bool {
241        self.0.eq(*other)
242    }
243}
244
245impl<Q: PartialOrd> PartialOrd<Q> for State<Q> {
246    fn partial_cmp(&self, other: &Q) -> Option<core::cmp::Ordering> {
247        self.0.partial_cmp(other)
248    }
249}
250
251impl<'a, Q: PartialOrd> PartialOrd<&'a Q> for State<Q> {
252    fn partial_cmp(&self, other: &&'a Q) -> Option<core::cmp::Ordering> {
253        self.0.partial_cmp(*other)
254    }
255}
256
257impl<'a, Q: PartialOrd> PartialOrd<&'a mut Q> for State<Q> {
258    fn partial_cmp(&self, other: &&'a mut Q) -> Option<core::cmp::Ordering> {
259        self.0.partial_cmp(*other)
260    }
261}
262
263unsafe impl<Q: Send> Send for State<Q> {}
264
265unsafe impl<Q: Sync> Sync for State<Q> {}