Crates.io | fsm-macro |
lib.rs | fsm-macro |
version | 0.1.0 |
source | src |
created_at | 2023-04-17 06:18:03.233816 |
updated_at | 2023-04-17 06:18:03.233816 |
description | A statically checked finite state machine written in rust. |
homepage | |
repository | https://github.com/OZoneGuy/rust-fsm |
max_upload_size | |
id | 841178 |
size | 14,982 |
A statically checked finite state machine written in rust.
Because I can. And I wanted to practice creating proc macros in rust. They can be fun...
To create a state machine, use the fsm
macro.
fsm!{
initial = init_state
state_1
state_2
...
end = end_state_1, end_state_2,...
state_n -> state_m: transition_k
...
}
// --snip--
// Initialize the finite state machine
let mut fsm = FSM::new();
// run transition and save new struct
fsm = fsm.transition_k();
let f = |from: &str, to: &str, event: &str| {
println!("from: {from}, to: {to}, event: {event}");
// other actions to be performed
}
// You can pass a callback function to be called with the transition
fsm = fsm.transition_l_fn(f);
// Call the end function. Confirm that the FSM reached a final state.
fsm.end();
// or pass a closure
f_end = |state: %str| {
println!("done!");
// maybe do something else as well...
}
fsm.end_fn(f_end);
The macro creates types for all the states and an FSM struct. The FSM struct is what the users should use. The state types allow it to define and restrict what transitions/functions can be called.
type struct state_1;
...
type struct FSM<T> {
...
pub history: Vec<Transition>,
}
type struct Transition{
pub from: String,
pub to: String,
pub event: string,
}
impl FSM {
pub fn new() -> FSM<initial_state> {
return FSM{
// initialization here
}
}
}
impl FSM<state_1> {
pub fn transition_k(self) -> FSM<state_2> {
return FSM {
// initialization here as well
}
}
pub fn transition_k_fn(self, f: Fn(&str, &str, &str)) -> FSM<state_2> {
f("state_1", "state_2", "transition_k");
return self.transition_k();
}
}
...
impl FSM<end_state> {
...
// note that it destroys the object.
// Do what you want with it before calling this function
pub fn end() {}
pub fn end_fn(f: Fn(&str)) {
f("end_state");
}
}
A -> B: a,b,c,...