1use super::{SharedStateError, SharedStorageView, SharedValue, WrongStateError};
2use crate::{
3 InnerInference, MayTransition, SMut, SRef, State, StateMachineImpl, StateStorage, StateTrait,
4 StateUnionRuntime, StateUnionState, Transition, TransitionCallsite,
5 state_trait::{self, ErasedState},
6};
7use core::marker::PhantomData;
8use core::ops::{Deref, DerefMut};
9
10pub struct StateRef<G, T, S> {
26 guard: G,
27 marker: PhantomData<fn() -> (T, S)>,
28}
29
30impl<G, T, S> StateRef<G, T, S>
31where
32 G: Deref<Target = SharedValue<T>>,
33 S: SharedBorrowState,
34{
35 pub(super) fn from_guard<StorageError>(
36 guard: G,
37 ) -> Result<Self, SharedStateError<StorageError>> {
38 S::ensure_state(&guard.state)?;
39 Ok(Self {
40 guard,
41 marker: PhantomData,
42 })
43 }
44}
45
46impl<G, T, S> Deref for StateRef<G, T, S>
47where
48 G: Deref<Target = SharedValue<T>>,
49{
50 type Target = T;
51
52 fn deref(&self) -> &Self::Target {
53 &self.guard.value
54 }
55}
56
57pub struct StorageStateRef<'a, Backend>(PhantomData<&'a Backend>);
66
67impl<'a, Backend> StateStorage for StorageStateRef<'a, Backend>
68where
69 Backend: SharedStorageView + 'a,
70{
71 type Inference = InnerInference;
72
73 type Inner<T, S>
74 = StateRef<Backend::ReadGuard<'a, T>, T, S>
75 where
76 T: StateMachineImpl;
77 type Machine<T>
78 = T
79 where
80 T: StateMachineImpl;
81
82 fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
83 where
84 T: StateMachineImpl,
85 {
86 StateRef {
87 guard: inner.guard,
88 marker: PhantomData,
89 }
90 }
91
92 fn inferred_state<T, S>(inner: &Self::Inner<T, S>) -> ErasedState
93 where
94 T: StateMachineImpl,
95 S: StateTrait,
96 {
97 state_trait::clone_erased(&inner.guard.state)
98 }
99}
100
101impl<'a, Backend> SRef for StorageStateRef<'a, Backend>
102where
103 Backend: SharedStorageView + 'a,
104{
105 fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
106 where
107 T: StateMachineImpl,
108 {
109 inner
110 }
111}
112
113pub struct StateMut<G, T, S>
137where
138 G: DerefMut<Target = SharedValue<T>>,
139{
140 guard: Option<G>,
141 pending: ErasedState,
142 marker: PhantomData<fn() -> (T, S)>,
143}
144
145pub struct StorageStateMut<'a, Backend>(PhantomData<&'a Backend>);
147
148impl<'a, Backend> StateStorage for StorageStateMut<'a, Backend>
149where
150 Backend: SharedStorageView + 'a,
151{
152 type Inference = InnerInference;
153
154 type Inner<T, S>
155 = StateMut<Backend::WriteGuard<'a, T>, T, S>
156 where
157 T: StateMachineImpl;
158 type Machine<T>
159 = T
160 where
161 T: StateMachineImpl;
162
163 fn retag<T, From, To>(mut inner: Self::Inner<T, From>) -> Self::Inner<T, To>
164 where
165 T: StateMachineImpl,
166 {
167 StateMut {
168 guard: inner.guard.take(),
169 pending: state_trait::clone_erased(&inner.pending),
170 marker: PhantomData,
171 }
172 }
173
174 fn inferred_state<T, S>(inner: &Self::Inner<T, S>) -> ErasedState
175 where
176 T: StateMachineImpl,
177 S: StateTrait,
178 {
179 state_trait::clone_erased(&inner.pending)
180 }
181}
182
183impl<'a, Backend> MayTransition for StorageStateMut<'a, Backend>
184where
185 Backend: SharedStorageView + 'a,
186{
187 fn complete_transition<T, From, To, Args>(
188 mut state: State<Self, T, From>,
189 _args: Args,
190 _callsite: TransitionCallsite,
191 ) -> State<Self, T, To>
192 where
193 T: StateMachineImpl,
194 From: StateTrait,
195 To: crate::ConcreteStateTrait,
196 T::Standin: Transition<From, To>,
197 <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
198 {
199 State {
200 inner: StateMut {
201 guard: state.inner.guard.take(),
202 pending: state_trait::erased_state::<To>(),
203 marker: PhantomData,
204 },
205 marker: PhantomData,
206 }
207 }
208
209 fn complete_transition_after_effect<T, From, To>(
210 mut state: State<Self, T, From>,
211 _callsite: TransitionCallsite,
212 ) -> State<Self, T, To>
213 where
214 T: StateMachineImpl,
215 From: StateTrait,
216 To: crate::ConcreteStateTrait,
217 {
218 State {
219 inner: StateMut {
220 guard: state.inner.guard.take(),
221 pending: state_trait::erased_state::<To>(),
222 marker: PhantomData,
223 },
224 marker: PhantomData,
225 }
226 }
227}
228
229impl<'a, Backend> SRef for StorageStateMut<'a, Backend>
230where
231 Backend: SharedStorageView + 'a,
232{
233 fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
234 where
235 T: StateMachineImpl,
236 {
237 inner
238 }
239}
240
241impl<'a, Backend> SMut for StorageStateMut<'a, Backend>
242where
243 Backend: SharedStorageView + 'a,
244{
245 fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
246 where
247 T: StateMachineImpl,
248 {
249 inner
250 }
251}
252
253impl<G, T, S> StateMut<G, T, S>
254where
255 G: DerefMut<Target = SharedValue<T>>,
256 S: SharedBorrowState,
257{
258 pub(super) fn from_guard<StorageError>(
259 guard: G,
260 ) -> Result<Self, SharedStateError<StorageError>> {
261 S::ensure_state(&guard.state)?;
262 let pending = S::initial_pending(&guard.state);
263 Ok(Self {
264 guard: Some(guard),
265 pending,
266 marker: PhantomData,
267 })
268 }
269}
270
271#[must_use]
275pub fn transition_mut<G, T, S, Next>(
276 state: StateMut<G, T, S>,
277 _token: T::TransitionToken,
278) -> StateMutTransitionCall<G, T, S, Next>
279where
280 G: DerefMut<Target = SharedValue<T>>,
281 T: StateMachineImpl,
282 T::Standin: Transition<S, Next>,
283{
284 StateMutTransitionCall {
285 state,
286 to: PhantomData,
287 }
288}
289
290impl<G, T, S> Deref for StateMut<G, T, S>
291where
292 G: DerefMut<Target = SharedValue<T>>,
293{
294 type Target = T;
295
296 fn deref(&self) -> &Self::Target {
297 &self.guard.as_ref().expect("guard is present").value
298 }
299}
300
301impl<G, T, S> DerefMut for StateMut<G, T, S>
302where
303 G: DerefMut<Target = SharedValue<T>>,
304{
305 fn deref_mut(&mut self) -> &mut Self::Target {
306 &mut self.guard.as_mut().expect("guard is present").value
307 }
308}
309
310impl<G, T, S> Drop for StateMut<G, T, S>
311where
312 G: DerefMut<Target = SharedValue<T>>,
313{
314 fn drop(&mut self) {
315 if let Some(guard) = self.guard.as_mut() {
316 guard.state = state_trait::clone_erased(&self.pending);
317 }
318 }
319}
320
321#[doc(hidden)]
323pub struct StateMutTransitionCall<G, T, From, To>
324where
325 G: DerefMut<Target = SharedValue<T>>,
326{
327 state: StateMut<G, T, From>,
328 to: PhantomData<fn() -> To>,
329}
330
331impl<G, T, From, To> StateMutTransitionCall<G, T, From, To>
332where
333 G: DerefMut<Target = SharedValue<T>>,
334{
335 pub fn call<Args>(mut self, _args: Args) -> StateMut<G, T, To>
336 where
337 T: StateMachineImpl,
338 T::Standin: Transition<From, To>,
339 <T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
340 To: crate::ConcreteStateTrait,
341 {
342 StateMut {
343 guard: self.state.guard.take(),
344 pending: state_trait::erased_state::<To>(),
345 marker: PhantomData,
346 }
347 }
348}
349
350#[doc(hidden)]
352pub trait SharedBorrowState: StateTrait {
353 fn ensure_state(actual: &ErasedState) -> Result<(), WrongStateError>;
354 fn initial_pending(actual: &ErasedState) -> ErasedState;
355}
356
357pub auto trait ExactSharedBorrowState {}
358
359impl<Marker> !ExactSharedBorrowState for StateUnionState<Marker> {}
360
361impl<S> SharedBorrowState for S
362where
363 S: crate::ConcreteStateTrait + ExactSharedBorrowState,
364{
365 fn ensure_state(actual: &ErasedState) -> Result<(), WrongStateError> {
366 if state_trait::is_state::<S>(actual) {
367 Ok(())
368 } else {
369 Err(WrongStateError {
370 expected: core::any::type_name::<S>(),
371 actual: actual.type_name(),
372 })
373 }
374 }
375
376 fn initial_pending(_actual: &ErasedState) -> ErasedState {
377 state_trait::erased_state::<S>()
378 }
379}
380
381impl<Marker> SharedBorrowState for StateUnionState<Marker>
382where
383 Marker: StateUnionRuntime + 'static,
384 StateUnionState<Marker>: StateTrait,
385{
386 fn ensure_state(actual: &ErasedState) -> Result<(), WrongStateError> {
387 if Marker::contains(&**actual) {
388 Ok(())
389 } else {
390 Err(WrongStateError {
391 expected: Marker::expected_type_name(),
392 actual: actual.type_name(),
393 })
394 }
395 }
396
397 fn initial_pending(actual: &ErasedState) -> ErasedState {
398 state_trait::clone_erased(actual)
399 }
400}