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