use crate::proto_state_machine::TopState;
#[allow(unused_imports)]
use crate::state_machine::StateMachine;
pub(crate) mod denatured {
pub struct OpaqueType {}
pub type StateFn = fn(*mut OpaqueType, &CoreEvt) -> CoreHandleResult;
pub type UserEvt = *const OpaqueType;
#[allow(unused)]
pub enum HandleResult {
Ignored,
Handled,
Transition(StateFn),
}
#[allow(unused)]
pub enum CoreHandleResult {
Ignored(ParentState),
Handled,
Transition(StateFn),
GetParentStateResult(ParentState),
InitResult(InitResult),
}
#[allow(unused)]
pub enum ParentState {
TopReached,
Exists(StateFn),
}
#[allow(unused)]
pub enum InitResult {
NotImplemented,
TargetState(StateFn),
}
#[allow(unused)]
pub enum CoreEvt<'a> {
InitEvt,
EntryEvt,
ExitEvt,
GetParentStateEvt,
UserEvt { user_evt: &'a UserEvt },
}
}
pub type StateFn<UserStateMachineT> = fn(
&mut UserStateMachineT,
&CoreEvt<<UserStateMachineT as TopState>::Evt>,
) -> CoreHandleResult<UserStateMachineT>;
pub enum HandleResult<UserStateMachineT: TopState + ?Sized> {
Ignored,
Handled,
Transition(StateFn<UserStateMachineT>),
}
pub enum CoreHandleResult<UserStateMachineT: TopState + ?Sized> {
Ignored(ParentState<UserStateMachineT>),
Handled,
Transition(StateFn<UserStateMachineT>),
GetParentStateResult(ParentState<UserStateMachineT>),
InitResult(InitResult<UserStateMachineT>),
}
pub enum ParentState<UserStateMachine: TopState + ?Sized> {
TopReached,
Exists(StateFn<UserStateMachine>),
}
pub enum InitResult<UserStateMachine: TopState + ?Sized> {
NotImplemented,
TargetState(StateFn<UserStateMachine>),
}
pub enum CoreEvt<'a, UserEvtT> {
InitEvt,
EntryEvt,
ExitEvt,
GetParentStateEvt,
UserEvt { user_evt: &'a UserEvtT },
}
pub trait State<Tag>
where
Self: TopState,
{
fn get_parent_state() -> ParentState<Self>;
fn init(&mut self) -> InitResult<Self> {
InitResult::NotImplemented
}
fn entry(&mut self) {
}
fn exit(&mut self) {
}
fn handle(&mut self, evt: &<Self as TopState>::Evt) -> HandleResult<Self>;
#[doc(hidden)]
fn core_handle(
&mut self,
evt: &CoreEvt<<Self as TopState>::Evt>,
) -> CoreHandleResult<Self> {
match evt {
CoreEvt::InitEvt => {
return CoreHandleResult::InitResult(<Self as State<Tag>>::init(self));
}
CoreEvt::EntryEvt => {
<Self as State<Tag>>::entry(self);
return CoreHandleResult::Handled;
}
CoreEvt::ExitEvt => {
<Self as State<Tag>>::exit(self);
return CoreHandleResult::Handled;
}
CoreEvt::GetParentStateEvt => {
return CoreHandleResult::GetParentStateResult(Self::get_parent_state());
}
CoreEvt::UserEvt { user_evt } => match <Self as State<Tag>>::handle(self, user_evt) {
HandleResult::Ignored => return CoreHandleResult::Ignored(Self::get_parent_state()),
HandleResult::Handled => return CoreHandleResult::Handled,
HandleResult::Transition(state_fn) => CoreHandleResult::Transition(state_fn),
},
}
}
}