Crates.io | generic-state-machine |
lib.rs | generic-state-machine |
version | 0.1.0 |
source | src |
created_at | 2023-09-24 06:35:42.311115 |
updated_at | 2023-09-24 06:35:42.311115 |
description | A simple Rust library that allows to create generic or Moore or Mealy state machines that allows the use of custom transition functions |
homepage | |
repository | https://github.com/klispap/generic-state-machine-rs |
max_upload_size | |
id | 981754 |
size | 24,748 |
A simple library that allows to create Moore or Mealy state machines
It is designed around the StateMachine<S,E>
type and allows the use of
custom transition functions.
S
E
self
(to have access to internal lists of states or events)
and need to follow the prototype:
fn(&mut StateMachine<S, E>, E) -> S;
where input E is the trigger event and the return value is the new state. +------------+
Event: 1 | | +----+
| V | | Event: 1
+->[false] [true]<--+
| | ^ |
+---+ | | Event: 0
Event: 0 +------------+
use state_machine::state_machine::AsyncStateMachine;
async fn main() -> Result<()> {
let mut fsm = AsyncStateMachine::<bool, usize>::new(5);
fsm.add_states(&mut vec![true, false])
.await
.add_transition(true, 0, |_fsm, _event| false)
.await
.add_transition(true, 1, |_fsm, _event| true)
.await
.add_transition(false, 0, |_fsm, _event| false)
.await
.add_transition(false, 1, |_fsm, _event| true)
.await
.set_state(false)
.await;
fsm.start().await.unwrap();
println!("State Machine under test: {:?}", fsm);
fsm.push_event(0).await.unwrap();
assert_eq!(fsm.current_state().await, false);
fsm.push_event(1).await.unwrap();
assert_eq!(fsm.current_state().await, true);
fsm.push_event(1).await.unwrap();
assert_eq!(fsm.current_state().await, true);
fsm.push_event(0).await.unwrap();
assert_eq!(fsm.current_state().await, false);
fsm.push_event(0).await.unwrap();
assert_eq!(fsm.current_state().await, false);
}
+---->[1]----+
Event: 1 | | Event: 2
| V
[3] [2]
^ |
| | Event: 3
+------------+
use state_machine::primitives::StateMachine;
// Define a transition function. It can as general as we want!
fn tf(_fsm: &mut StateMachine<i32, i32>, event: i32) -> i32 {
match event {
1 => 1,
2 => 2,
3 => 3,
_ => panic!(), // Invalid transition
}
}
let mut fsm = StateMachine::<i32, i32>::new();
fsm.add_states(&mut vec![1, 2, 3]);
// We can even use captures as transition functions!
fsm.add_transition(1, 2, |_fsm, _event| {
// We are in state 1! Go to state 2! Ignore Input!
2
});
// If you prefer you can chain configuration methods together
fsm.add_transition(2, 3, tf)
.add_transition(3, 1, tf)
.set_state(1);
println!("{:?}", fsm);
assert_eq!(&1, fsm.execute(1));
assert_eq!(&2, fsm.execute(2));
assert_eq!(&3, fsm.execute(3));