use super::{
MayTransition, SMapRuntime, SMove, SMut, SPinMut, SPinRef, SRef, State, StateStorage,
StateStorageNew, TransitionCallsite,
};
use crate::state::owned::{StateOwned, complete_transition};
use crate::{Initial, StateMachineImpl, Transition};
use core::marker::PhantomData;
use core::pin::Pin;
#[cfg(feature = "unique-rc-arc")]
use std::rc::UniqueRc;
#[cfg(feature = "unique-rc-arc")]
use std::sync::UniqueArc;
pub struct StorageStateOwned;
pub type SOwned = StorageStateOwned;
pub struct StorageStateOwnedBox;
pub struct StorageStateOwnedPinBox;
#[cfg(feature = "unique-rc-arc")]
pub struct StorageStateOwnedUniqueRc;
#[cfg(feature = "unique-rc-arc")]
pub struct StorageStateOwnedUniqueArc;
impl StateStorage for StorageStateOwned {
type Inner<T, S>
= StateOwned<T, S>
where
T: StateMachineImpl;
type Machine<T>
= T
where
T: StateMachineImpl;
fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
where
T: StateMachineImpl,
{
super::retag_owned(inner)
}
}
impl MayTransition for StorageStateOwned {
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>,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
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,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
}
impl StateStorageNew for StorageStateOwned {
fn new<T, S>(value: T) -> Self::Inner<T, S>
where
T: StateMachineImpl,
T::Standin: Initial<S>,
{
StateOwned::new(value)
}
}
impl SRef for StorageStateOwned {
fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
where
T: StateMachineImpl,
{
&inner.value
}
}
impl SMut for StorageStateOwned {
fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
where
T: StateMachineImpl,
{
&mut inner.value
}
}
impl SMove for StorageStateOwned {}
impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for StorageStateOwned
where
FromRuntime: StateMachineImpl,
ToRuntime: StateMachineImpl,
{
fn map_runtime<S, F>(state: State<Self, FromRuntime, S>, f: F) -> State<Self, ToRuntime, S>
where
F: FnOnce(FromRuntime) -> ToRuntime,
{
State {
inner: StateOwned {
value: f(state.inner.value),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
macro_rules! indirect_owned_storage {
($storage:ty, $wrapper:ident) => {
impl StateStorage for $storage {
type Inner<T, S>
= StateOwned<$wrapper<T>, S>
where
T: StateMachineImpl;
type Machine<T>
= $wrapper<T>
where
T: StateMachineImpl;
fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
where
T: StateMachineImpl,
{
super::retag_owned(inner)
}
}
impl MayTransition for $storage {
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>,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
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,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
}
impl StateStorageNew for $storage {
fn new<T, S>(value: T) -> Self::Inner<T, S>
where
T: StateMachineImpl,
<Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
{
StateOwned::new($wrapper::new(value))
}
}
impl SRef for $storage {
fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
where
T: StateMachineImpl,
{
&inner.value
}
}
impl SMut for $storage {
fn s_mut<T, S>(inner: &mut Self::Inner<T, S>) -> &mut T
where
T: StateMachineImpl,
{
&mut inner.value
}
}
impl SMove for $storage {}
};
($storage:ty, $wrapper:ident, $map:path) => {
indirect_owned_storage!($storage, $wrapper);
impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for $storage
where
FromRuntime: StateMachineImpl,
ToRuntime: StateMachineImpl,
{
fn map_runtime<S, F>(
state: State<Self, FromRuntime, S>,
f: F,
) -> State<Self, ToRuntime, S>
where
F: FnOnce(FromRuntime) -> ToRuntime,
{
State {
inner: StateOwned {
value: $map(state.inner.value, f),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}
};
}
fn map_box<FromRuntime, ToRuntime, F>(value: Box<FromRuntime>, f: F) -> Box<ToRuntime>
where
F: FnOnce(FromRuntime) -> ToRuntime,
{
Box::new(f(*value))
}
indirect_owned_storage!(StorageStateOwnedBox, Box, map_box);
#[cfg(feature = "unique-rc-arc")]
indirect_owned_storage!(StorageStateOwnedUniqueRc, UniqueRc);
#[cfg(feature = "unique-rc-arc")]
indirect_owned_storage!(StorageStateOwnedUniqueArc, UniqueArc);
impl StateStorage for StorageStateOwnedPinBox {
type Inner<T, S>
= StateOwned<Pin<Box<T>>, S>
where
T: StateMachineImpl;
type Machine<T>
= Pin<Box<T>>
where
T: StateMachineImpl;
fn retag<T, From, To>(inner: Self::Inner<T, From>) -> Self::Inner<T, To>
where
T: StateMachineImpl,
{
super::retag_owned(inner)
}
}
impl MayTransition for StorageStateOwnedPinBox {
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>,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
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,
{
State {
inner: complete_transition(state.inner, callsite),
marker: PhantomData,
}
}
}
impl StateStorageNew for StorageStateOwnedPinBox {
fn new<T, S>(value: T) -> Self::Inner<T, S>
where
T: StateMachineImpl,
<Self::Machine<T> as StateMachineImpl>::Standin: Initial<S>,
{
StateOwned::new(Box::pin(value))
}
}
impl SRef for StorageStateOwnedPinBox {
fn s_ref<T, S>(inner: &Self::Inner<T, S>) -> &T
where
T: StateMachineImpl,
{
&inner.value
}
}
impl SPinRef for StorageStateOwnedPinBox {
fn s_pin_ref<T, S>(inner: &Self::Inner<T, S>) -> Pin<&T>
where
T: StateMachineImpl,
{
inner.value.as_ref()
}
}
impl SPinMut for StorageStateOwnedPinBox {
fn s_pin_mut<T, S>(inner: &mut Self::Inner<T, S>) -> Pin<&mut T>
where
T: StateMachineImpl,
{
inner.value.as_mut()
}
}
impl SMove for StorageStateOwnedPinBox {}
impl<FromRuntime, ToRuntime> SMapRuntime<FromRuntime, ToRuntime> for StorageStateOwnedPinBox
where
FromRuntime: StateMachineImpl + Unpin,
ToRuntime: StateMachineImpl,
{
fn map_runtime<S, F>(state: State<Self, FromRuntime, S>, f: F) -> State<Self, ToRuntime, S>
where
F: FnOnce(FromRuntime) -> ToRuntime,
{
State {
inner: StateOwned {
value: Box::pin(f(*Pin::into_inner(state.inner.value))),
state: PhantomData,
#[cfg(feature = "tracing")]
trace: state.inner.trace,
},
marker: PhantomData,
}
}
}