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