Remix.run Logo
throwaway894345 a day ago

I’m probably doing it wrong, but when there’s a state with multiple transitions out, I can either model it as distinct methods per transition in which case the caller needs to know how to transition between states or I can have the caller pass an enum in which moves the branch into the state machine at the expense of an enum and a match statement. It’s also like 10x the code. Again, I’m very open to the possibility that I’m doing something wrong. Curious how you would model a state machine for (1) reserving the right to do the inventory (2) querying the next page of results (based on a cursor) and (3) recording the page information and the next cursor.

vatsachak a day ago | parent [-]

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 11 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 24 minutes 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?