mod owned;
use crate::{
ConcreteStateKind, DiscriminatedState, Initial, StateConcreteProvenState,
StateConcreteTransitionProof, StateKind, StateMachineImpl, StateUnionDiscriminant,
StateUnionDiscriminatedTransition, StateUnionErased, StateUnionProofTarget,
StateUnionProvenState, StateUnionSharedEffect, StateUnionSharedTransitionEffect,
StateUnionTransitionProof, StateWithProof, Transition, UnionStateKind, state_trait,
};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "tracing")]
use alloc::vec::Vec;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
#[cfg(feature = "tracing")]
use core::panic::Location;
use core::pin::Pin;
#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
use std::rc::UniqueRc;
#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
use std::sync::UniqueArc;
pub use owned::{SOwned, StorageStateOwned};
#[cfg(feature = "alloc")]
pub use owned::{StorageStateOwnedBox, StorageStateOwnedPinBox};
#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
pub use owned::{StorageStateOwnedUniqueArc, StorageStateOwnedUniqueRc};
#[cfg(feature = "alloc")]
pub type SBox<T, S> = State<StorageStateOwnedBox, T, S>;
#[cfg(feature = "alloc")]
pub type SPinBox<T, S> = State<StorageStateOwnedPinBox, T, S>;
fn retag_owned<T, From, To>(inner: crate::StateOwned<T, From>) -> crate::StateOwned<T, To> {
crate::StateOwned {
value: inner.value,
state: PhantomData,
#[cfg(feature = "tracing")]
trace: inner.trace,
}
}
type StateMarker<Storage, T, S> = PhantomData<fn() -> (Storage, T, S)>;
type TransitionMarker<Storage, T, From, To> = PhantomData<fn() -> (Storage, T, From, To)>;
#[doc(hidden)]
pub trait TransitionEffectSelector<From, To>: StateMachineImpl {
type Effect;
}
#[doc(hidden)]
pub trait PinnedTransitionEffectSelector<From, To>: StateMachineImpl {
type Effect;
}
#[doc(hidden)]
pub trait TransitionEffect<T, From, To, Args>
where
T: StateMachineImpl,
{
fn apply(value: &mut T, args: Args);
}
#[doc(hidden)]
pub trait PinnedTransitionEffect<T, From, To, Args>
where
T: StateMachineImpl,
{
fn apply(value: Pin<&mut T>, args: Args);
}
#[doc(hidden)]
pub trait InferenceKind {
type Inference: StateInference;
}
#[doc(hidden)]
pub trait StateInference {
fn new<Storage, T, S>(inner: &Storage::Inner<T, S>) -> Self
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::ConcreteStateTrait;
fn from_erased(state: state_trait::ErasedState) -> Self;
fn state<Storage, T, S>(&self, inner: &Storage::Inner<T, S>) -> state_trait::ErasedState
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::StateTrait;
}
#[doc(hidden)]
pub struct OuterInference;
#[doc(hidden)]
pub struct InnerInference;
#[doc(hidden)]
#[derive(Clone, Copy)]
pub struct InnerStateInference;
impl InferenceKind for OuterInference {
type Inference = state_trait::ErasedState;
}
impl InferenceKind for InnerInference {
type Inference = InnerStateInference;
}
impl StateInference for state_trait::ErasedState {
fn new<Storage, T, S>(_inner: &Storage::Inner<T, S>) -> Self
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::ConcreteStateTrait,
{
state_trait::erased_state::<S>()
}
fn from_erased(state: state_trait::ErasedState) -> Self {
state
}
fn state<Storage, T, S>(&self, _inner: &Storage::Inner<T, S>) -> state_trait::ErasedState
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::StateTrait,
{
state_trait::clone_erased(self)
}
}
impl StateInference for InnerStateInference {
fn new<Storage, T, S>(_inner: &Storage::Inner<T, S>) -> Self
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::ConcreteStateTrait,
{
Self
}
fn from_erased(_state: state_trait::ErasedState) -> Self {
Self
}
fn state<Storage, T, S>(&self, inner: &Storage::Inner<T, S>) -> state_trait::ErasedState
where
Storage: StateStorage,
T: StateMachineImpl,
S: crate::StateTrait,
{
Storage::inferred_state(inner)
}
}
pub trait StateStorage: Sized {
type Inference: InferenceKind = OuterInference;
type Inner<T, S>
where
T: StateMachineImpl;
type Machine<T>: StateMachineImpl<Standin = T::Standin, Impl = T::Impl, TransitionToken = T::TransitionToken>
where
T: StateMachineImpl;
#[doc(hidden)]
fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
where
T: StateMachineImpl;
#[doc(hidden)]
fn inferred_state<T, State>(inner: &Self::Inner<T, State>) -> state_trait::ErasedState
where
T: StateMachineImpl,
State: crate::StateTrait,
{
let _ = inner;
state_trait::static_erased_state::<State>()
}
}
pub trait MayTransition: StateStorage {
fn complete_transition<T, From, To, Args>(
state: State<Self, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Self, T, To>
where
T: StateMachineImpl,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>;
#[doc(hidden)]
fn complete_transition_after_effect<T, From, To>(
state: State<Self, T, From>,
callsite: TransitionCallsite,
) -> State<Self, T, To>
where
T: StateMachineImpl,
From: crate::StateTrait,
To: crate::ConcreteStateTrait;
}
#[doc(hidden)]
pub fn complete_transition_after_effect<Storage, T, From, To>(
state: State<Storage, T, From>,
callsite: TransitionCallsite,
) -> State<Storage, T, To>
where
Storage: MayTransition,
T: StateMachineImpl,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
{
Storage::complete_transition_after_effect(state, callsite)
}
pub trait StateStorageNew: StateStorage {
fn new<T, State>(value: T) -> Self::Inner<T, State>
where
T: StateMachineImpl,
<Self::Machine<T> as StateMachineImpl>::Standin: Initial<State>;
}
pub trait SRef: StateStorage {
fn s_ref<T, State>(inner: &Self::Inner<T, State>) -> &T
where
T: StateMachineImpl;
}
pub trait SMut: SRef + MayTransition {
fn s_mut<T, State>(inner: &mut Self::Inner<T, State>) -> &mut T
where
T: StateMachineImpl;
}
pub trait SPinRef: SRef {
fn s_pin_ref<T, State>(inner: &Self::Inner<T, State>) -> Pin<&T>
where
T: StateMachineImpl;
}
pub trait SPinMut: SPinRef + MayTransition {
fn s_pin_mut<T, State>(inner: &mut Self::Inner<T, State>) -> Pin<&mut T>
where
T: StateMachineImpl;
}
pub trait SMove: MayTransition {}
pub trait SMapRuntime<FromRuntime, ToRuntime>: SMove
where
FromRuntime: StateMachineImpl,
ToRuntime: StateMachineImpl,
{
fn map_runtime<StateMarkerType, F>(
state: State<Self, FromRuntime, StateMarkerType>,
f: F,
) -> State<Self, ToRuntime, StateMarkerType>
where
F: FnOnce(FromRuntime) -> ToRuntime;
}
pub struct State<Storage, T, S>
where
T: StateMachineImpl,
Storage: StateStorage,
{
pub(crate) inner: Storage::Inner<T, S>,
pub(crate) marker: StateMarker<Storage, T, S>,
}
pub struct ConcreteStated<T, S>
where
S: crate::StateMarker<Kind = ConcreteStateKind>,
{
value: T,
state: PhantomData<fn() -> S>,
}
impl<T, S> ConcreteStated<T, S>
where
S: crate::StateMarker<Kind = ConcreteStateKind>,
{
#[allow(unsafe_code)]
#[must_use]
pub unsafe fn new(value: T) -> Self {
Self {
value,
state: PhantomData,
}
}
#[must_use]
pub fn into_raw(self) -> T {
self.value
}
}
#[doc(hidden)]
#[must_use]
pub fn concrete_stated_new<T, S>(value: T, _token: T::TransitionToken) -> ConcreteStated<T, S>
where
T: StateMachineImpl,
S: crate::ConcreteStateTrait,
{
ConcreteStated {
value,
state: PhantomData,
}
}
#[allow(type_alias_bounds)]
pub type SResult<Storage, T, OkState, ErrState>
where
Storage: StateStorage,
T: StateMachineImpl,
= Result<State<Storage, T, OkState>, State<Storage, T, ErrState>>;
#[doc(hidden)]
pub struct StateTransitionCall<Storage, T, From, To>
where
T: StateMachineImpl,
Storage: StateStorage,
{
state: State<Storage, T, From>,
#[cfg(feature = "tracing")]
callsite: &'static Location<'static>,
marker: TransitionMarker<Storage, T, From, To>,
}
#[doc(hidden)]
pub struct EffectTransitionCall<Storage, T, From, To, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> (To, Effect)>,
}
#[doc(hidden)]
pub struct PinnedEffectTransitionCall<Storage, T, From, To, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> (To, Effect)>,
}
#[doc(hidden)]
pub struct ConcreteProofTransitionCall<Storage, T, From, To>
where
T: StateMachineImpl,
Storage: StateStorage,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> To>,
}
#[doc(hidden)]
pub struct KindProofTransitionCall<Storage, T, From, Marker, To, Kind>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
Marker: crate::StateMarker,
To: crate::ConcreteStateTrait,
Kind: StateKind,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> (Marker, To, Kind)>,
}
#[doc(hidden)]
pub struct StateUnionProofTransitionCall<Storage, T, From, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
Marker: StateUnionDiscriminant,
To: crate::ConcreteStateTrait,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> (Marker, To)>,
}
#[doc(hidden)]
pub struct PinnedStateUnionProofTransitionCall<Storage, T, From, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
Marker: StateUnionDiscriminant,
To: crate::ConcreteStateTrait,
{
state: State<Storage, T, From>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> (Marker, To)>,
}
#[doc(hidden)]
pub struct DiscriminatedTransitionCall<Storage, T, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
{
state: DiscriminatedState<Storage, T, Marker>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> To>,
}
#[doc(hidden)]
pub struct PinnedDiscriminatedTransitionCall<Storage, T, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
{
state: DiscriminatedState<Storage, T, Marker>,
callsite: TransitionCallsite,
marker: PhantomData<fn() -> To>,
}
#[cfg(feature = "tracing")]
#[doc(hidden)]
pub type TransitionCallsite = &'static Location<'static>;
#[cfg(not(feature = "tracing"))]
#[doc(hidden)]
pub type TransitionCallsite = ();
#[doc(hidden)]
#[track_caller]
pub fn transition_callsite() -> TransitionCallsite {
#[cfg(feature = "tracing")]
{
Location::caller()
}
#[cfg(not(feature = "tracing"))]
{}
}
impl<Storage, T, From, To> StateTransitionCall<Storage, T, From, To>
where
T: StateMachineImpl,
Storage: StateStorage,
{
#[doc(hidden)]
pub fn call<Args>(self, args: Args) -> State<Storage, T, To>
where
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
Storage: MayTransition,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
{
Storage::complete_transition(self.state, args, {
#[cfg(feature = "tracing")]
{
self.callsite
}
#[cfg(not(feature = "tracing"))]
{}
})
}
}
impl<Storage, T, From, To, Effect> EffectTransitionCall<Storage, T, From, To, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
Storage: SMut,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Effect: TransitionEffect<T, From, To, Args>,
{
Effect::apply(Storage::s_mut(&mut self.state.inner), args);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, From, To, Effect> PinnedEffectTransitionCall<Storage, T, From, To, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
Storage: SPinMut,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Effect: PinnedTransitionEffect<T, From, To, Args>,
{
Effect::apply(Storage::s_pin_mut(&mut self.state.inner), args);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, From, To> ConcreteProofTransitionCall<Storage, T, From, To>
where
T: StateMachineImpl,
Storage: StateStorage,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
T: TransitionEffectSelector<From, To>,
Storage: SMut,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
<T as TransitionEffectSelector<From, To>>::Effect: TransitionEffect<T, From, To, Args>,
{
<T as TransitionEffectSelector<From, To>>::Effect::apply(
Storage::s_mut(&mut self.state.inner),
args,
);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, From, Marker, To>
KindProofTransitionCall<Storage, T, From, Marker, To, ConcreteStateKind>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Marker: crate::StateMarker,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
T: TransitionEffectSelector<From, To>,
Storage: SMut,
T::Standin: Transition<From, To>,
<T::Standin as Transition<From, To>>::F: crate::TransitionSignature<Args>,
From: crate::ConcreteStateTrait,
To: crate::ConcreteStateTrait,
<T as TransitionEffectSelector<From, To>>::Effect: TransitionEffect<T, From, To, Args>,
{
<T as TransitionEffectSelector<From, To>>::Effect::apply(
Storage::s_mut(&mut self.state.inner),
args,
);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, From, Marker, To>
KindProofTransitionCall<Storage, T, From, Marker, To, UnionStateKind>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Marker: StateUnionDiscriminant,
{
pub fn call<Args>(self, args: Args) -> State<Storage, T, To>
where
Storage: SMut,
From: crate::StateTrait + crate::In<Marker>,
Marker: StateUnionDiscriminatedTransition<T, To, Args>,
To: crate::ConcreteStateTrait,
{
let state = <From as crate::In<Marker>>::into_discriminated(self.state);
Marker::transition(state, args, self.callsite)
}
}
impl<Storage, T, From, Marker, To> StateUnionProofTransitionCall<Storage, T, From, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Marker: StateUnionDiscriminant,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
Storage: SMut,
From: StateUnionErased<Marker>,
Marker: StateUnionSharedTransitionEffect<T, To, Args>,
To: crate::ConcreteStateTrait,
{
Marker::apply(Storage::s_mut(&mut self.state.inner), args);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, From, Marker, To> PinnedStateUnionProofTransitionCall<Storage, T, From, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Marker: StateUnionDiscriminant,
{
pub fn call<Args>(mut self, args: Args) -> State<Storage, T, To>
where
Storage: SPinMut,
From: StateUnionErased<Marker>,
Marker: crate::StateUnionSharedPinnedTransitionEffect<T, To, Args>,
To: crate::ConcreteStateTrait,
{
Marker::apply_pinned(Storage::s_pin_mut(&mut self.state.inner), args);
Storage::complete_transition_after_effect(self.state, self.callsite)
}
}
impl<Storage, T, Marker, To> DiscriminatedTransitionCall<Storage, T, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
{
pub fn call<Args>(self, args: Args) -> State<Storage, T, To>
where
Storage: SMut,
Marker: StateUnionDiscriminatedTransition<T, To, Args>,
To: crate::ConcreteStateTrait,
{
Marker::transition(self.state, args, self.callsite)
}
}
impl<Storage, T, Marker, To> PinnedDiscriminatedTransitionCall<Storage, T, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
{
pub fn call<Args>(self, args: Args) -> State<Storage, T, To>
where
Storage: SPinMut,
Marker: crate::StateUnionDiscriminatedPinnedTransition<T, To, Args>,
To: crate::ConcreteStateTrait,
{
Marker::pinned_transition(self.state, args, self.callsite)
}
}
#[must_use]
#[track_caller]
pub fn transition_state<Storage, T, S, Next>(
state: State<Storage, T, S>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> StateTransitionCall<Storage, T, S, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
T::Standin: Transition<S, Next>,
S: crate::StateTrait,
Next: crate::ConcreteStateTrait,
{
StateTransitionCall {
state,
#[cfg(feature = "tracing")]
callsite: Location::caller(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_effect<Storage, T, S, Next, Effect>(
state: State<Storage, T, S>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> EffectTransitionCall<Storage, T, S, Next, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
T::Standin: Transition<S, Next>,
S: crate::StateTrait,
Next: crate::ConcreteStateTrait,
{
EffectTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_pinned_effect<Storage, T, S, Next, Effect>(
state: State<Storage, T, S>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> PinnedEffectTransitionCall<Storage, T, S, Next, Effect>
where
T: StateMachineImpl,
Storage: StateStorage,
T::Standin: Transition<S, Next>,
S: crate::StateTrait,
Next: crate::ConcreteStateTrait,
{
PinnedEffectTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_static_union_pinned_proof<Storage, T, S, Marker, Next>(
state: State<Storage, T, S>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> PinnedStateUnionProofTransitionCall<Storage, T, S, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: crate::StateTrait + StateUnionErased<Marker>,
Marker: StateUnionDiscriminant + crate::StateUnionSharedPinnedEffect<T, Next>,
Next: crate::ConcreteStateTrait,
{
PinnedStateUnionProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_union_proof<Storage, T, S, Marker, Next>(
proven: StateUnionProvenState<Storage, T, S, Marker, Next>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> StateUnionProofTransitionCall<Storage, T, S, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: StateUnionErased<Marker>,
Marker: StateUnionSharedEffect<T, Next>,
Next: crate::ConcreteStateTrait,
{
StateUnionProofTransitionCall {
state: proven.state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_concrete_proof<Storage, T, S, Marker, Next>(
proven: StateConcreteProvenState<Storage, T, S, Marker, Next>,
token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> EffectTransitionCall<Storage, T, S, Next, <T as TransitionEffectSelector<S, Next>>::Effect>
where
T: StateMachineImpl + TransitionEffectSelector<S, Next>,
Storage: StateStorage,
T::Standin: Transition<S, Next>,
Marker: StateUnionDiscriminant,
S: crate::StateTrait,
Next: crate::ConcreteStateTrait,
{
transition_state_with_effect(proven.state, token)
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_concrete_transition_proof<Storage, T, S, Marker, Next>(
proven: StateWithProof<Storage, T, S, StateConcreteTransitionProof<T, S, Marker, Next>>,
token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> EffectTransitionCall<Storage, T, S, Next, <T as TransitionEffectSelector<S, Next>>::Effect>
where
T: StateMachineImpl + TransitionEffectSelector<S, Next>,
Storage: StateStorage,
T::Standin: Transition<S, Next>,
Marker: StateUnionDiscriminant,
S: crate::StateTrait,
Next: crate::ConcreteStateTrait,
{
let StateWithProof {
state,
proof: _proof,
} = proven;
transition_state_with_effect(state, token)
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_union_transition_proof<Storage, T, S, Marker, Next>(
proven: StateWithProof<Storage, T, S, StateUnionTransitionProof<T, S, Marker, Next>>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> StateUnionProofTransitionCall<Storage, T, S, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: StateUnionErased<Marker>,
Marker: StateUnionSharedEffect<T, Next>,
Next: crate::ConcreteStateTrait,
{
let StateWithProof {
state,
proof: _proof,
} = proven;
StateUnionProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_static_union_proof<Storage, T, S, Marker, Next>(
state: State<Storage, T, S>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> StateUnionProofTransitionCall<Storage, T, S, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: crate::StateTrait + StateUnionErased<Marker> + crate::UnionTransitionProof<T, Marker, Next>,
Marker: StateUnionDiscriminant + StateUnionSharedEffect<T, Next>,
Next: crate::ConcreteStateTrait,
{
StateUnionProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_erased_transition_proof<Storage, T, S, Marker, Next, Proof>(
proven: StateWithProof<Storage, T, S, Proof>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> StateUnionProofTransitionCall<Storage, T, S, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: crate::StateTrait,
Marker: StateUnionDiscriminant,
Next: crate::ConcreteStateTrait,
{
let StateWithProof {
state,
proof: _proof,
} = proven;
StateUnionProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_concrete_kind_proof<Storage, T, S, Marker, Next, Kind>(
proven: StateWithProof<
Storage,
T,
S,
crate::TransitionProof<Storage, T, S, Marker, Next, Kind>,
>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> ConcreteProofTransitionCall<Storage, T, S, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
S: crate::StateTrait,
Marker: crate::StateMarker,
Next: crate::ConcreteStateTrait,
Kind: StateKind,
{
let StateWithProof {
state,
proof: _proof,
} = proven;
ConcreteProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_state_with_kind_proof<Storage, T, S, Marker, Next, Kind>(
proven: StateWithProof<
Storage,
T,
S,
crate::TransitionProof<Storage, T, S, Marker, Next, Kind>,
>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> KindProofTransitionCall<Storage, T, S, Marker, Next, Kind>
where
T: StateMachineImpl,
Storage: StateStorage,
S: crate::StateTrait,
Marker: crate::StateMarker,
Next: crate::ConcreteStateTrait,
Kind: StateKind,
{
let StateWithProof {
state,
proof: _proof,
} = proven;
KindProofTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
pub fn transition_concrete_after_effect<Storage, T, From, To, Args, Effect>(
mut state: State<Storage, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Storage, T, To>
where
T: StateMachineImpl,
Storage: SMut,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Effect: TransitionEffect<T, From, To, Args>,
{
Effect::apply(Storage::s_mut(&mut state.inner), args);
Storage::complete_transition_after_effect(state, callsite)
}
#[doc(hidden)]
pub fn transition_concrete_after_pinned_effect<Storage, T, From, To, Args, Effect>(
mut state: State<Storage, T, From>,
args: Args,
callsite: TransitionCallsite,
) -> State<Storage, T, To>
where
T: StateMachineImpl,
Storage: SPinMut,
From: crate::StateTrait,
To: crate::ConcreteStateTrait,
Effect: PinnedTransitionEffect<T, From, To, Args>,
{
Effect::apply(Storage::s_pin_mut(&mut state.inner), args);
Storage::complete_transition_after_effect(state, callsite)
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_discriminated_state<Storage, T, Marker, Next>(
state: DiscriminatedState<Storage, T, Marker>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> DiscriminatedTransitionCall<Storage, T, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
Next: crate::StateTrait,
{
DiscriminatedTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
#[track_caller]
pub fn transition_discriminated_state_pinned<Storage, T, Marker, Next>(
state: DiscriminatedState<Storage, T, Marker>,
_token: <Storage::Machine<T> as StateMachineImpl>::TransitionToken,
) -> PinnedDiscriminatedTransitionCall<Storage, T, Marker, Next>
where
T: StateMachineImpl,
Storage: StateStorage,
Marker: StateUnionDiscriminant,
Next: crate::StateTrait,
{
PinnedDiscriminatedTransitionCall {
state,
callsite: transition_callsite(),
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
pub fn proven_state<To, Storage, T, S>(
state: State<Storage, T, S>,
) -> StateUnionProvenState<Storage, T, S, <To as StateUnionProofTarget<T, S>>::Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
S: StateUnionErased<<To as StateUnionProofTarget<T, S>>::Marker>,
To: StateUnionProofTarget<T, S>,
{
StateUnionProvenState {
state,
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
pub fn proven_union_state<Marker, To, Storage, T, S>(
state: State<Storage, T, S>,
) -> StateUnionProvenState<Storage, T, S, Marker, To>
where
T: StateMachineImpl,
Storage: StateStorage,
S: StateUnionErased<Marker>,
Marker: StateUnionSharedEffect<T, To>,
To: crate::ConcreteStateTrait,
{
StateUnionProvenState {
state,
marker: PhantomData,
}
}
#[must_use]
pub fn pin_ref<Storage, T, S>(state: &State<Storage, T, S>) -> Pin<&T>
where
T: StateMachineImpl,
Storage: SPinRef,
{
Storage::s_pin_ref(&state.inner)
}
pub fn pin_mut<Storage, T, S>(state: &mut State<Storage, T, S>) -> Pin<&mut T>
where
T: StateMachineImpl,
Storage: SPinMut,
{
Storage::s_pin_mut(&mut state.inner)
}
impl<Storage, T, S> State<Storage, T, S>
where
T: StateMachineImpl,
Storage: StateStorage,
{
pub(crate) fn from_inner(inner: Storage::Inner<T, S>) -> Self {
Self {
inner,
marker: PhantomData,
}
}
#[doc(hidden)]
#[must_use]
pub fn with<Marker, To, Kind>(
self,
proof: crate::TransitionProof<Storage, T, S, Marker, To, Kind>,
) -> StateWithProof<Storage, T, S, crate::TransitionProof<Storage, T, S, Marker, To, Kind>>
where
S: crate::StateTrait,
Marker: crate::StateMarker,
To: crate::ConcreteStateTrait,
Kind: crate::StateKind,
{
StateWithProof { state: self, proof }
}
}
impl<T, S> State<StorageStateOwned, T, S>
where
T: StateMachineImpl,
{
#[must_use]
pub fn new(value: T) -> Self
where
T::Standin: Initial<S>,
{
State {
inner: <StorageStateOwned as StateStorageNew>::new(value),
marker: PhantomData,
}
}
#[must_use]
pub fn from_concrete(value: ConcreteStated<T, S>) -> Self
where
S: crate::ConcreteStateTrait,
{
State {
inner: crate::StateOwned {
value: value.into_raw(),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: Vec::new(),
},
marker: PhantomData,
}
}
#[must_use]
pub fn into_concrete(state: Self) -> ConcreteStated<T, S>
where
S: crate::ConcreteStateTrait,
{
ConcreteStated {
value: state.inner.value,
state: PhantomData,
}
}
}
#[cfg(feature = "alloc")]
impl<T, S> State<StorageStateOwnedBox, T, S>
where
T: StateMachineImpl,
{
#[must_use]
pub fn new(state: State<StorageStateOwned, T, S>) -> Self {
State {
inner: crate::StateOwned {
value: Box::new(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
#[must_use]
pub fn unbox(state: Self) -> State<StorageStateOwned, T, S> {
State {
inner: crate::StateOwned {
value: *state.inner.value,
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
#[cfg(feature = "alloc")]
impl<T, S> State<StorageStateOwnedPinBox, T, S>
where
T: StateMachineImpl,
{
#[must_use]
pub fn new(state: State<StorageStateOwnedBox, T, S>) -> Self {
State {
inner: crate::StateOwned {
value: Box::into_pin(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
#[must_use]
pub fn into_boxed(state: Self) -> State<StorageStateOwnedBox, T, S>
where
T: Unpin,
{
State {
inner: crate::StateOwned {
value: Pin::into_inner(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
impl<T, S> State<StorageStateOwnedUniqueRc, T, S>
where
T: StateMachineImpl,
{
#[must_use]
pub fn new(state: State<StorageStateOwned, T, S>) -> Self {
State {
inner: crate::StateOwned {
value: UniqueRc::new(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
#[cfg(all(feature = "std", feature = "unique-rc-arc"))]
impl<T, S> State<StorageStateOwnedUniqueArc, T, S>
where
T: StateMachineImpl,
{
#[must_use]
pub fn new(state: State<StorageStateOwned, T, S>) -> Self {
State {
inner: crate::StateOwned {
value: UniqueArc::new(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
impl<Storage, T, S> Deref for State<Storage, T, S>
where
T: StateMachineImpl,
Storage: SRef,
{
type Target = T;
fn deref(&self) -> &Self::Target {
Storage::s_ref(&self.inner)
}
}
impl<Storage, T, S> DerefMut for State<Storage, T, S>
where
T: StateMachineImpl,
Storage: SMut,
{
fn deref_mut(&mut self) -> &mut Self::Target {
Storage::s_mut(&mut self.inner)
}
}