Define your Finite State Machines in DOT
I've not wanted to change my crate for a couple of months now, so I guess it's time to tell you all about it :)
fsmentry, allows you to define your state machines like this, which I find much easier than existing crates:
fsmentry::dot!{
red -> amber -> green -> red
}
But that's not all - fsmentry machines can:
- store arbitrary data inside each state - including other state machines!
- transition themselves with a nice
.entry()API - support arbitrary
#[derive(..)]s - document themselves with nice diagrams
Here's a fuller example:
// Using the DSL allows us to add derives and data in each state
fsmentry::dsl! {
#[derive(Debug)]
pub User {
Reading;
Commenting: String; // data in this state
Reading -> Commenting -> Reading;
Commenting -> Sleeping;
/// Doc comments are plumbed to the right places
Reading -"that's enough"-> Sleeping;
}
}
use user::{Entry::{Commenting, Reading, Sleeping}, State, User};
let mut user = User::new(State::Reading);
loop {
match user.entry() {
Commenting(it) => {
// access the data
let comment: &String = it.get();
if contains_bad_words(comment) {
// transition to one state or the other
it.sleeping();
} else {
it.reading();
}
}
// provide the state for this transition
Reading(it) => it.commenting(String::from("I've read it")),
Sleeping => break,
}
}
I felt like I could add something that other crates don't cover - check out the comparison with other crates in the README