Skip to main content

magicstatemachines/state/storage/
owned.rs

1use super::{
2    SMove, SMut, SPinMut, SPinRef, SRef, State, StateStorage, StateStorageNew, TransitionCallsite,
3};
4use crate::state::owned::{StateOwned, complete_transition};
5use crate::{Initial, StateMachineImpl, Transition};
6use core::marker::PhantomData;
7use core::pin::Pin;
8#[cfg(feature = "unique-rc-arc")]
9use std::rc::UniqueRc;
10#[cfg(feature = "unique-rc-arc")]
11use std::sync::UniqueArc;
12
13/// Backend for directly owned values.
14pub struct StorageStateOwned;
15
16/// Short alias for [`StorageStateOwned`].
17pub type SOwned = StorageStateOwned;
18
19/// Backend for `Box<T>` owned values.
20pub struct StorageStateOwnedBox;
21
22/// Backend for `Pin<Box<T>>` owned values.
23pub struct StorageStateOwnedPinBox;
24
25/// Backend for `UniqueRc<T>` owned values.
26#[cfg(feature = "unique-rc-arc")]
27pub struct StorageStateOwnedUniqueRc;
28
29/// Backend for `UniqueArc<T>` owned values.
30#[cfg(feature = "unique-rc-arc")]
31pub struct StorageStateOwnedUniqueArc;
32
33impl StateStorage for StorageStateOwned {
34    type Inner<T, S>
35        = StateOwned<T, S>
36    where
37        T: StateMachineImpl;
38    type Machine<T>
39        = T
40    where
41        T: StateMachineImpl;
42
43    fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
44    where
45        T: StateMachineImpl,
46    {
47        super::retag_owned(inner)
48    }
49
50    fn complete_transition<T, From, To, Args>(
51        state: State<Self, T, From>,
52        _args: Args,
53        callsite: TransitionCallsite,
54    ) -> State<Self, T, To>
55    where
56        T: StateMachineImpl,
57        From: crate::StateTrait,
58        To: crate::ConcreteStateTrait,
59        T::Standin: Transition<From, To>,
60        <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
61    {
62        State {
63            inner: complete_transition(state.inner, callsite),
64            marker: PhantomData,
65        }
66    }
67
68    fn complete_transition_after_effect<T, From, To>(
69        state: State<Self, T, From>,
70        callsite: TransitionCallsite,
71    ) -> State<Self, T, To>
72    where
73        T: StateMachineImpl,
74        From: crate::StateTrait,
75        To: crate::ConcreteStateTrait,
76    {
77        State {
78            inner: complete_transition(state.inner, callsite),
79            marker: PhantomData,
80        }
81    }
82}
83
84impl StateStorageNew for StorageStateOwned {
85    fn new<T, S>(value: T) -> Self::Inner<T, S>
86    where
87        T: StateMachineImpl,
88        T::Standin: Initial<S>,
89    {
90        StateOwned::new(value)
91    }
92}
93
94impl SRef for StorageStateOwned {
95    fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
96    where
97        T: StateMachineImpl,
98    {
99        &inner.value
100    }
101}
102
103impl SMut for StorageStateOwned {
104    fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
105    where
106        T: StateMachineImpl,
107    {
108        &mut inner.value
109    }
110}
111
112impl SMove for StorageStateOwned {}
113
114macro_rules! indirect_owned_storage {
115    ($storage:ty, $wrapper:ident) => {
116        impl StateStorage for $storage {
117            type Inner<T, S>
118                = StateOwned<$wrapper<T>, S>
119            where
120                T: StateMachineImpl;
121            type Machine<T>
122                = $wrapper<T>
123            where
124                T: StateMachineImpl;
125
126            fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
127            where
128                T: StateMachineImpl,
129            {
130                super::retag_owned(inner)
131            }
132
133            fn complete_transition<T, From, To, Args>(
134                state: State<Self, T, From>,
135                _args: Args,
136                callsite: TransitionCallsite,
137            ) -> State<Self, T, To>
138            where
139                T: StateMachineImpl,
140                From: crate::StateTrait,
141                To: crate::ConcreteStateTrait,
142                T::Standin: Transition<From, To>,
143                <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
144            {
145                State {
146                    inner: complete_transition(state.inner, callsite),
147                    marker: PhantomData,
148                }
149            }
150
151            fn complete_transition_after_effect<T, From, To>(
152                state: State<Self, T, From>,
153                callsite: TransitionCallsite,
154            ) -> State<Self, T, To>
155            where
156                T: StateMachineImpl,
157                From: crate::StateTrait,
158                To: crate::ConcreteStateTrait,
159            {
160                State {
161                    inner: complete_transition(state.inner, callsite),
162                    marker: PhantomData,
163                }
164            }
165        }
166
167        impl StateStorageNew for $storage {
168            fn new<T, S>(value: T) -> Self::Inner<T, S>
169            where
170                T: StateMachineImpl,
171                <Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
172            {
173                StateOwned::new($wrapper::new(value))
174            }
175        }
176
177        impl SRef for $storage {
178            fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
179            where
180                T: StateMachineImpl,
181            {
182                &inner.value
183            }
184        }
185
186        impl SMut for $storage {
187            fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
188            where
189                T: StateMachineImpl,
190            {
191                &mut inner.value
192            }
193        }
194
195        impl SMove for $storage {}
196    };
197}
198
199indirect_owned_storage!(StorageStateOwnedBox, Box);
200#[cfg(feature = "unique-rc-arc")]
201indirect_owned_storage!(StorageStateOwnedUniqueRc, UniqueRc);
202#[cfg(feature = "unique-rc-arc")]
203indirect_owned_storage!(StorageStateOwnedUniqueArc, UniqueArc);
204
205impl StateStorage for StorageStateOwnedPinBox {
206    type Inner<T, S>
207        = StateOwned<Pin<Box<T>>, S>
208    where
209        T: StateMachineImpl;
210    type Machine<T>
211        = Pin<Box<T>>
212    where
213        T: StateMachineImpl;
214
215    fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
216    where
217        T: StateMachineImpl,
218    {
219        super::retag_owned(inner)
220    }
221
222    fn complete_transition<T, From, To, Args>(
223        state: State<Self, T, From>,
224        _args: Args,
225        callsite: TransitionCallsite,
226    ) -> State<Self, T, To>
227    where
228        T: StateMachineImpl,
229        From: crate::StateTrait,
230        To: crate::ConcreteStateTrait,
231        T::Standin: Transition<From, To>,
232        <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
233    {
234        State {
235            inner: complete_transition(state.inner, callsite),
236            marker: PhantomData,
237        }
238    }
239
240    fn complete_transition_after_effect<T, From, To>(
241        state: State<Self, T, From>,
242        callsite: TransitionCallsite,
243    ) -> State<Self, T, To>
244    where
245        T: StateMachineImpl,
246        From: crate::StateTrait,
247        To: crate::ConcreteStateTrait,
248    {
249        State {
250            inner: complete_transition(state.inner, callsite),
251            marker: PhantomData,
252        }
253    }
254}
255
256impl StateStorageNew for StorageStateOwnedPinBox {
257    fn new<T, S>(value: T) -> Self::Inner<T, S>
258    where
259        T: StateMachineImpl,
260        <Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
261    {
262        StateOwned::new(Box::pin(value))
263    }
264}
265
266impl SRef for StorageStateOwnedPinBox {
267    fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
268    where
269        T: StateMachineImpl,
270    {
271        &inner.value
272    }
273}
274
275impl SPinRef for StorageStateOwnedPinBox {
276    fn s_pin_ref<T, S>(inner: &Self::Inner<T, S>) -> Pin<&T>
277    where
278        T: StateMachineImpl,
279    {
280        inner.value.as_ref()
281    }
282}
283
284impl SPinMut for StorageStateOwnedPinBox {
285    fn s_pin_mut<T, S>(inner: &mut Self::Inner<T, S>) -> Pin<&mut T>
286    where
287        T: StateMachineImpl,
288    {
289        inner.value.as_mut()
290    }
291}
292
293impl SMove for StorageStateOwnedPinBox {}