pub trait StateStorage: Sized {
type Inner<T, S>
where T: StateMachineImpl;
type Machine<T>: StateMachineImpl<Standin = T::Standin, Impl = T::Impl, TransitionToken = T::TransitionToken>
where T: StateMachineImpl;
type Inference: InferenceKind = OuterInference;
// Required method
fn complete_transition<T, From, To, Args>(
state: State<Self, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Self, T, To>
where T: StateMachineImpl,
From: StateTrait,
To: ConcreteStateTrait,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: TransitionSignature<Args>;
}Expand description
Storage backend used by State.
State<Storage, T, S> is only a typed view; the actual representation is
selected by this trait. The same implementation methods can therefore work
for directly owned values, boxed values, pinned values, shared guard views,
and discriminated union views as long as they ask for the right capability
bound.
Backend authors provide an Inner<T, S> generic associated type. The
library retags that Inner after a successful transition, so the backend
controls where data is stored while the state-machine contract still
controls which retags are legal.
Most users do not implement this trait. They choose one of the built-in storage aliases and write bounds on methods:
use magicstatemachines::{SRef, SMut, State, transition};
use test_def::{InOnline, Online};
use test_def::states::{Authenticated, Connected};
impl Connection {
fn endpoint<S>(self: &State<S, Self, impl InOnline>) -> &str
where
S: SRef,
{
&self.endpoint
}
fn authenticate<S>(
self: State<S, Self, Connected>,
user: String,
) -> State<S, Self, Authenticated>
where
S: SMut,
{
transition!(self, user)
}
}Required Associated Types§
Sourcetype Inner<T, S>
where
T: StateMachineImpl
type Inner<T, S> where T: StateMachineImpl
Concrete state representation used by this storage backend.
Sourcetype Machine<T>: StateMachineImpl<Standin = T::Standin, Impl = T::Impl, TransitionToken = T::TransitionToken>
where
T: StateMachineImpl
type Machine<T>: StateMachineImpl<Standin = T::Standin, Impl = T::Impl, TransitionToken = T::TransitionToken> where T: StateMachineImpl
Type that carries the state-machine implementation contract.
Provided Associated Types§
Sourcetype Inference: InferenceKind = OuterInference
type Inference: InferenceKind = OuterInference
Selects how SDiscriminated recovers the current state marker.
Required Methods§
Sourcefn complete_transition<T, From, To, Args>(
state: State<Self, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Self, T, To>where
T: StateMachineImpl,
From: StateTrait,
To: ConcreteStateTrait,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: TransitionSignature<Args>,
fn complete_transition<T, From, To, Args>(
state: State<Self, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Self, T, To>where
T: StateMachineImpl,
From: StateTrait,
To: ConcreteStateTrait,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: TransitionSignature<Args>,
Retags a state after checking that Args matches the declared transition signature.
Storage backends normally delegate this to their inner representation.
Implementation crates should call transitions through transition!
rather than invoking this method directly.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".