| Crates.io | rust-automata |
| lib.rs | rust-automata |
| version | 0.0.3 |
| created_at | 2025-04-22 22:35:56.156176+00 |
| updated_at | 2025-04-26 16:41:05.775201+00 |
| description | A framework and a DSL for building finite state machines in Rust |
| homepage | https://github.com/michalsustr/rust-automata |
| repository | https://github.com/michalsustr/rust-automata |
| max_upload_size | |
| id | 1644769 |
| size | 53,761 |
The rust-automata crate provides a simple DSL for building finite state machines in Rust with minimum effort, using proc macros from the rust-automata-macros crate.
The rust-automata directly implement Mealy machines:
A Mealy machine is a tuple (S, s0, Σ, Λ, T) consisting of the following:
S the machine can be in,s0 which is an element of S,Σ the machine can receive,Λ the machine can output,T : S × Σ → S × Λ mapping pairs of a state and an input symbol to the corresponding next state and output symbol.Additionally:
Nothing symbol.See examples for more examples.
Here is a simple example to give a quick taste:
TODO: use timer for vikings
mod example {
use rust_automata::*;
#[state_machine(
inputs(I1, I2),
states(S1, S2, S3),
outputs(O1, O2),
transitions(
(S1, I1) -> (S2, O1) = handle_transition,
(S2, I2) -> (S3, O2),
(S2, I1) -> (S3, O2) : guard_never,
(S3, I1) -> (S1, O1),
(S3) -> (S3, O1),
),
generate_structs(true),
derive(Debug, PartialEq),
)]
pub struct Example;
impl Example {
fn handle_transition(&mut self, state: S1, input: I1) -> (S2, O1) {
println!("handle_transition called");
(S2, O1)
}
fn guard_never(&self, state: &S2) -> bool { false }
}
}
use example::*;
use rust_automata::*;
// Create a new state machine.
let mut m = StateMachine::new(Example, S1);
// Relay an input. Prints "handle_transition called".
let output: O1 = m.relay(I1);
assert!(m.state().is_s2());
// Consume an input.
assert!(!m.can_consume::<I1>()); // Can't consume because of the guard.
assert!(m.can_consume::<I2>());
m.consume(I2);
assert!(m.state().is_s3());
// Produce an output, no input is needed.
let output: O1 = m.produce();
assert!(m.state().is_s3());
// Cycle in the absorbing state.
m.step();
m.step();
m.step();
assert!(m.state().is_s3());
This crate is still under active development. Expect breaking changes.
Here are some of the things that are planned.
Major:
Minor (soon):
should_panic for invalid transitionsIf you have any suggestions, please open an issue or a PR. Also, I'd be happy if you star the repo!
mermaid - generate Mermaid state diagrams in the doc strings.dsl (default) - re-export the DSL into doc strings.To see an example of a state machine without DSL (useful for debugging), install cargo-expand and run:
cd examples
cargo expand lock # Or any other example.
rust-fsm crate.takeable repo.