Skip to main content

magicstatemachines/
util.rs

1use crate::{In, State, StateMachineImpl, StateStorage, StateUnionDiscriminant};
2
3/// Convenience extension for converting a state into a union's generated enum.
4///
5/// This is implemented for every generated union marker. It is most useful
6/// when the marker value is already in scope and you want the concrete enum
7/// immediately, without spelling the associated [`In`](crate::In) conversion
8/// and then calling `discriminate()` yourself:
9///
10/// ```ignore
11/// use magicstatemachines::EnumExt;
12/// use test_def::{Online, OnlineEnum};
13///
14/// let online = Online.into_enum(state);
15///
16/// match online {
17///     OnlineEnum::Connected(connected) => {
18///         // `connected` has the concrete `Connected` state marker.
19///     }
20///     OnlineEnum::Authenticated(authenticated) => {
21///         // `authenticated` has the concrete `Authenticated` state marker.
22///     }
23/// }
24/// ```
25pub trait EnumExt: StateUnionDiscriminant {
26    /// Converts `state` into this union's generated enum.
27    ///
28    /// The input state may be any concrete state that implements `In<Self>`.
29    /// The output is the enum associated with this marker, for example
30    /// `OnlineEnum<S, Connection>` for marker `Online`.
31    fn into_enum<S, T, Current>(
32        self,
33        state: State<S, T, Current>,
34    ) -> <Self as StateUnionDiscriminant>::Enum<S, T>
35    where
36        S: StateStorage,
37        T: StateMachineImpl,
38        Current: In<Self>,
39    {
40        <Current as In<Self>>::into_discriminated(state).discriminate()
41    }
42}
43
44impl<T: StateUnionDiscriminant> EnumExt for T {}