Preview
Open Original
Yo, so I published a new major version of this lib I created and have been using for every state machine like code I work on, specially on embedded systems, with which I work the most.
The rust_sfsm attribute macro can be used on structs and creates the boilerplate for any type implementing a state-like behavior.
Example
/// List of protocol states.
#[derive(Clone, Copy, Default, PartialEq)]
enum States {
#[default]
Init,
Opened,
Closed,
Locked,
}
/// List of protocol events.
enum Events {
Create,
Open,
Close,
Lock,
Unlock,
}
/// Protocol state machine context (data shared between states).
#[derive(Default)]
struct Context {
lock_counter: u16,
}
impl StateBeh...
Yo, so I published a new major version of this lib I created and have been using for every state machine like code I work on, specially on embedded systems, with which I work the most.
The rust_sfsm attribute macro can be used on structs and creates the boilerplate for any type implementing a state-like behavior.
Example
/// List of protocol states.
#[derive(Clone, Copy, Default, PartialEq)]
enum States {
#[default]
Init,
Opened,
Closed,
Locked,
}
/// List of protocol events.
enum Events {
Create,
Open,
Close,
Lock,
Unlock,
}
/// Protocol state machine context (data shared between states).
#[derive(Default)]
struct Context {
lock_counter: u16,
}
impl StateBehavior for States {
type State = Self;
type Event<'a> = Events;
type Context = Context;
fn enter(&self, _context: &mut Self::Context) {
if self == &States::Locked {
_context.lock_counter += 1
}
}
fn handle_event(
&self,
event: &Self::Event<'_>,
_context: &mut Self::Context,
) -> Option<Self::State> {
match (self, event) {
(&States::Init, &Events::Create) => Some(States::Opened),
(&States::Opened, &Events::Close) => Some(States::Closed),
(&States::Closed, &Events::Open) => Some(States::Opened),
(&States::Closed, &Events::Lock) => Some(States::Locked),
(&States::Locked, &Events::Unlock) => Some(States::Closed),
_ => None,
}
}
}
#[rust_sfsm(states = States, context = Context)]
#[derive(Default)]
struct Protocol {}
fn main() {
let mut protocol = Protocol::default();
test_state_machine(&mut protocol);
}
fn test_state_machine<S: StateMachine<States>>(state_machine: &mut S) {
assert!(state_machine.current_state() == States::Init);
state_machine.handle_event(&Events::Create);
assert!(state_machine.current_state() == States::Opened);
state_machine.handle_event(&Events::Close);
assert!(state_machine.current_state() == States::Closed);
state_machine.handle_event(&Events::Lock);
assert!(state_machine.current_state() == States::Locked);
state_machine.handle_event(&Events::Unlock);
assert!(state_machine.current_state() == States::Closed);
state_machine.handle_event(&Events::Open);
assert!(state_machine.current_state() == States::Opened);
}