1use super::{
2 MayTransition, SMapRuntime, SMove, SMut, SRef, State, StateStorage, StateStorageNew,
3 TransitionCallsite,
4};
5#[cfg(feature = "alloc")]
6use super::{SPinMut, SPinRef};
7use crate::state::owned::{StateOwned, complete_transition};
8use crate::{Initial, StateMachineImpl, Transition};
9#[cfg(feature = "alloc")]
10use alloc::boxed::Box;
11use core::marker::PhantomData;
12#[cfg(feature = "alloc")]
13use core::pin::Pin;
14#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
15use std::rc::UniqueRc;
16#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
17use std::sync::UniqueArc;
18
19pub struct StorageStateOwned;
21
22pub type SOwned = StorageStateOwned;
24
25#[cfg(feature = "alloc")]
27pub struct StorageStateOwnedBox;
28
29#[cfg(feature = "alloc")]
31pub struct StorageStateOwnedPinBox;
32
33#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
35pub struct StorageStateOwnedUniqueRc;
36
37#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
39pub struct StorageStateOwnedUniqueArc;
40
41impl StateStorage for StorageStateOwned {
42 type Inner<T, S>
43 = StateOwned<T, S>
44 where
45 T: StateMachineImpl;
46 type Machine<T>
47 = T
48 where
49 T: StateMachineImpl;
50
51 fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
52 where
53 T: StateMachineImpl,
54 {
55 super::retag_owned(inner)
56 }
57}
58
59impl MayTransition for StorageStateOwned {
60 fn complete_transition<T, From, To, Args>(
61 state: State<Self, T, From>,
62 _args: Args,
63 callsite: TransitionCallsite,
64 ) -> State<Self, T, To>
65 where
66 T: StateMachineImpl,
67 From: crate::StateTrait,
68 To: crate::ConcreteStateTrait,
69 T::Standin: Transition<From, To>,
70 <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
71 {
72 State {
73 inner: complete_transition(state.inner, callsite),
74 marker: PhantomData,
75 }
76 }
77
78 fn complete_transition_after_effect<T, From, To>(
79 state: State<Self, T, From>,
80 callsite: TransitionCallsite,
81 ) -> State<Self, T, To>
82 where
83 T: StateMachineImpl,
84 From: crate::StateTrait,
85 To: crate::ConcreteStateTrait,
86 {
87 State {
88 inner: complete_transition(state.inner, callsite),
89 marker: PhantomData,
90 }
91 }
92}
93
94impl StateStorageNew for StorageStateOwned {
95 fn new<T, S>(value: T) -> Self::Inner<T, S>
96 where
97 T: StateMachineImpl,
98 T::Standin: Initial<S>,
99 {
100 StateOwned::new(value)
101 }
102}
103
104impl SRef for StorageStateOwned {
105 fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
106 where
107 T: StateMachineImpl,
108 {
109 &inner.value
110 }
111}
112
113impl SMut for StorageStateOwned {
114 fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
115 where
116 T: StateMachineImpl,
117 {
118 &mut inner.value
119 }
120}
121
122impl SMove for StorageStateOwned {}
123
124impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for StorageStateOwned
125where
126 FromRuntime: StateMachineImpl,
127 ToRuntime: StateMachineImpl,
128{
129 fn map_runtime<S, F>(state: State<Self, FromRuntime, S>, f: F) -> State<Self, ToRuntime, S>
130 where
131 F: FnOnce(FromRuntime) -> ToRuntime,
132 {
133 State {
134 inner: StateOwned {
135 value: f(state.inner.value),
136 state: PhantomData,
137 #[cfg(feature = "tracing")]
138 trace: state.inner.trace,
139 },
140 marker: PhantomData,
141 }
142 }
143}
144
145#[cfg(any(feature = "alloc", all(feature = "std", feature = "unique-rc-arc")))]
146macro_rules! indirect_owned_storage {
147 ($storage:ty, $wrapper:ident) => {
148 impl StateStorage for $storage {
149 type Inner<T, S>
150 = StateOwned<$wrapper<T>, S>
151 where
152 T: StateMachineImpl;
153 type Machine<T>
154 = $wrapper<T>
155 where
156 T: StateMachineImpl;
157
158 fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
159 where
160 T: StateMachineImpl,
161 {
162 super::retag_owned(inner)
163 }
164 }
165
166 impl MayTransition for $storage {
167 fn complete_transition<T, From, To, Args>(
168 state: State<Self, T, From>,
169 _args: Args,
170 callsite: TransitionCallsite,
171 ) -> State<Self, T, To>
172 where
173 T: StateMachineImpl,
174 From: crate::StateTrait,
175 To: crate::ConcreteStateTrait,
176 T::Standin: Transition<From, To>,
177 <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
178 {
179 State {
180 inner: complete_transition(state.inner, callsite),
181 marker: PhantomData,
182 }
183 }
184
185 fn complete_transition_after_effect<T, From, To>(
186 state: State<Self, T, From>,
187 callsite: TransitionCallsite,
188 ) -> State<Self, T, To>
189 where
190 T: StateMachineImpl,
191 From: crate::StateTrait,
192 To: crate::ConcreteStateTrait,
193 {
194 State {
195 inner: complete_transition(state.inner, callsite),
196 marker: PhantomData,
197 }
198 }
199 }
200
201 impl StateStorageNew for $storage {
202 fn new<T, S>(value: T) -> Self::Inner<T, S>
203 where
204 T: StateMachineImpl,
205 <Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
206 {
207 StateOwned::new($wrapper::new(value))
208 }
209 }
210
211 impl SRef for $storage {
212 fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
213 where
214 T: StateMachineImpl,
215 {
216 &inner.value
217 }
218 }
219
220 impl SMut for $storage {
221 fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
222 where
223 T: StateMachineImpl,
224 {
225 &mut inner.value
226 }
227 }
228
229 impl SMove for $storage {}
230 };
231
232 ($storage:ty, $wrapper:ident, $map:path) => {
233 indirect_owned_storage!($storage, $wrapper);
234 impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for $storage
235 where
236 FromRuntime: StateMachineImpl,
237 ToRuntime: StateMachineImpl,
238 {
239 fn map_runtime<S, F>(
240 state: State<Self, FromRuntime, S>,
241 f: F,
242 ) -> State<Self, ToRuntime, S>
243 where
244 F: FnOnce(FromRuntime) -> ToRuntime,
245 {
246 State {
247 inner: StateOwned {
248 value: $map(state.inner.value, f),
249 state: PhantomData,
250 #[cfg(feature = "tracing")]
251 trace: state.inner.trace,
252 },
253 marker: PhantomData,
254 }
255 }
256 }
257 };
258}
259
260#[cfg(feature = "alloc")]
261fn map_box<FromRuntime, ToRuntime, F>(value: Box<FromRuntime>, f: F) -> Box<ToRuntime>
262where
263 F: FnOnce(FromRuntime) -> ToRuntime,
264{
265 Box::new(f(*value))
266}
267
268#[cfg(feature = "alloc")]
269indirect_owned_storage!(StorageStateOwnedBox, Box, map_box);
270
271#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
272indirect_owned_storage!(StorageStateOwnedUniqueRc, UniqueRc);
273#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
274indirect_owned_storage!(StorageStateOwnedUniqueArc, UniqueArc);
275
276#[cfg(feature = "alloc")]
277impl StateStorage for StorageStateOwnedPinBox {
278 type Inner<T, S>
279 = StateOwned<Pin<Box<T>>, S>
280 where
281 T: StateMachineImpl;
282 type Machine<T>
283 = Pin<Box<T>>
284 where
285 T: StateMachineImpl;
286
287 fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
288 where
289 T: StateMachineImpl,
290 {
291 super::retag_owned(inner)
292 }
293}
294
295#[cfg(feature = "alloc")]
296impl MayTransition for StorageStateOwnedPinBox {
297 fn complete_transition<T, From, To, Args>(
298 state: State<Self, T, From>,
299 _args: Args,
300 callsite: TransitionCallsite,
301 ) -> State<Self, T, To>
302 where
303 T: StateMachineImpl,
304 From: crate::StateTrait,
305 To: crate::ConcreteStateTrait,
306 T::Standin: Transition<From, To>,
307 <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
308 {
309 State {
310 inner: complete_transition(state.inner, callsite),
311 marker: PhantomData,
312 }
313 }
314
315 fn complete_transition_after_effect<T, From, To>(
316 state: State<Self, T, From>,
317 callsite: TransitionCallsite,
318 ) -> State<Self, T, To>
319 where
320 T: StateMachineImpl,
321 From: crate::StateTrait,
322 To: crate::ConcreteStateTrait,
323 {
324 State {
325 inner: complete_transition(state.inner, callsite),
326 marker: PhantomData,
327 }
328 }
329}
330
331#[cfg(feature = "alloc")]
332impl StateStorageNew for StorageStateOwnedPinBox {
333 fn new<T, S>(value: T) -> Self::Inner<T, S>
334 where
335 T: StateMachineImpl,
336 <Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
337 {
338 StateOwned::new(Box::pin(value))
339 }
340}
341
342#[cfg(feature = "alloc")]
343impl SRef for StorageStateOwnedPinBox {
344 fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
345 where
346 T: StateMachineImpl,
347 {
348 &inner.value
349 }
350}
351
352#[cfg(feature = "alloc")]
353impl SPinRef for StorageStateOwnedPinBox {
354 fn s_pin_ref<T, S>(inner: &Self::Inner<T, S>) -> Pin<&T>
355 where
356 T: StateMachineImpl,
357 {
358 inner.value.as_ref()
359 }
360}
361
362#[cfg(feature = "alloc")]
363impl SPinMut for StorageStateOwnedPinBox {
364 fn s_pin_mut<T, S>(inner: &mut Self::Inner<T, S>) -> Pin<&mut T>
365 where
366 T: StateMachineImpl,
367 {
368 inner.value.as_mut()
369 }
370}
371
372#[cfg(feature = "alloc")]
373impl SMove for StorageStateOwnedPinBox {}
374
375#[cfg(feature = "alloc")]
376impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for StorageStateOwnedPinBox
377where
378 FromRuntime: StateMachineImpl + Unpin,
379 ToRuntime: StateMachineImpl,
380{
381 fn map_runtime<S, F>(state: State<Self, FromRuntime, S>, f: F) -> State<Self, ToRuntime, S>
382 where
383 F: FnOnce(FromRuntime) -> ToRuntime,
384 {
385 State {
386 inner: StateOwned {
387 value: Box::pin(f(*Pin::into_inner(state.inner.value))),
388 state: PhantomData,
389 #[cfg(feature = "tracing")]
390 trace: state.inner.trace,
391 },
392 marker: PhantomData,
393 }
394 }
395}