#[derive(Debug)]
pub(crate) enum State<S, R> {
Next(S),
Return(R, S),
}
pub(crate) trait StateMachine {
type State;
type Return;
type Error;
fn take_state(&mut self) -> Self::State;
fn put_state(&mut self, state: Self::State);
}
pub(crate) fn turn<SM, F>(state_machine: &mut SM, mut f: F) -> Result<SM::Return, SM::Error>
where
SM: StateMachine,
F: FnMut(SM::State, &mut SM) -> Result<State<SM::State, SM::Return>, SM::Error>,
{
let mut current_state = state_machine.take_state();
loop {
match f(current_state, state_machine) {
Ok(State::Next(next)) => {
current_state = next;
}
Ok(State::Return(value, next)) => {
state_machine.put_state(next);
return Ok(value);
}
Err(e) => {
return Err(e);
}
}
}
}
pub(crate) fn err<S, R, E>(e: E) -> Result<State<S, R>, E> {
Err(e)
}
pub(crate) fn next<S, R, E>(next_state: S) -> Result<State<S, R>, E> {
Ok(State::Next(next_state))
}
pub(crate) fn ret<S, R, E>(retval: R, next_state: S) -> Result<State<S, R>, E> {
Ok(State::Return(retval, next_state))
}