Remix.run Logo
vatsachak a day ago

In the type state pattern you would have something like this

pub trait ValidState {}

struct StateMachine<'a, T>

where

  T: ValidState 
{

untyped: &'a mut UntypedStateMachine,

_marker: PhantomData<T>

}

fn reserve_right<'a>(state: StateMachine<'a, Begin>) -> StateMachine<'a, Reserved>

fn query<'a>(state: StateMachine<'a, Reserved>) -> StateMachine<'a, Queried>

fn record<'a>(state: StateMachine<'a, Queried>) -> StateMachine<'a, Recorded>

throwaway894345 14 hours ago | parent [-]

How do you model cases where the reservation fails, where the inventory operation is already complete, etc? Basically conditional transitions based on some data received? Also, where does the actual I/O happen? Presumably there is some shell that drives the state machine that does the I/O before or after executing the transition?

vatsachak 12 hours ago | parent [-]

The I/O is done using the mutable reference to the UntypedStateMachine in the functions.

For example UntypedStateMachine could just be a vec that you append to or read from.

If you want to model cases with failure your return type will be

Result<StateMachine<Reserved>, Error>

A conditional transition should return something like

(StateMachine<PostConditional>, ConditionalData)

throwaway894345 an hour ago | parent [-]

I think this makes sense. I’m eager to try it. Some residual questions: what is “untyped” in this case and what is “PostConditional” (an enum of possible states?)? How do subsequent transitions work?