pub struct StateMachine<T> {
function: Option<StateFn<T>>,
}
type StateFn<T> = fn(&mut T) -> StateMachine<T>;
impl<T> StateMachine<T> {
pub fn new(function: Option<StateFn<T>>) -> StateMachine<T> {
StateMachine { function }
}
pub fn next(function: StateFn<T>) -> StateMachine<T> {
StateMachine::new(Some(function))
}
pub fn finish() -> StateMachine<T> {
StateMachine::new(None)
}
pub fn run(machine: &mut T, starting_state_fn: StateFn<T>) {
let mut state_machine = StateMachine::new(Some(starting_state_fn));
while let Some(state_fn) = state_machine.function {
state_machine = state_fn(machine);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
struct DummyMachine {
private_data_s1: bool,
private_data_s2: bool,
private_data_s3: bool,
}
impl DummyMachine {
fn new() -> Self {
DummyMachine {
private_data_s1: false,
private_data_s2: false,
private_data_s3: false,
}
}
fn run(&mut self) {
assert!(!self.private_data_s1);
assert!(!self.private_data_s2);
assert!(!self.private_data_s3);
StateMachine::run(self, Self::s1);
assert!(self.private_data_s1);
assert!(self.private_data_s2);
assert!(self.private_data_s3);
}
fn s1(&mut self) -> StateMachine<Self> {
assert!(!self.private_data_s1);
self.private_data_s1 = true;
StateMachine::next(Self::s2)
}
fn s2(&mut self) -> StateMachine<Self> {
assert!(!self.private_data_s2);
self.private_data_s2 = true;
StateMachine::next(Self::s3)
}
fn s3(&mut self) -> StateMachine<Self> {
assert!(!self.private_data_s3);
self.private_data_s3 = true;
StateMachine::finish()
}
}
#[test]
fn test_sm() {
let mut machine = DummyMachine::new();
machine.run();
}
}