Finite state machines in rust; bendns fork to add types.
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 77 |
1 files changed, 27 insertions, 50 deletions
@@ -7,8 +7,8 @@ The `rust-fsm` crate provides a simple and universal framework for building state machines in Rust with minimum effort. The essential part of this crate is the `StateMachineImpl` trait. This trait -allows a developer to provide a strict state machine definition, e.g. -specify its: +allows a developer to provide a strict state machine definition, e.g. specify +its: * An input alphabet - a set of entities that the state machine takes as inputs and performs state transitions based on them. @@ -30,7 +30,7 @@ of state machines: * A Moore machine by providing an output function that do not depend on the provided inputs. -## Features +## Usage in `no_std` environments This library has the feature named `std` which is enabled by default. You may want to import this library as @@ -46,7 +46,7 @@ also enabled by default. Initially this library was designed to build an easy to use DSL for defining state machines on top of it. Using the DSL will require to connect an additional crate `rust-fsm-dsl` (this is due to limitation of the procedural -macros system). +macros system). ### Using the DSL for defining state machines @@ -57,24 +57,21 @@ use rust_fsm::*; state_machine! { derive(Debug) - repr_c(true) - CircuitBreaker(Closed) + circuit_breaker(Closed) Closed(Unsuccessful) => Open [SetupTimer], Open(TimerTriggered) => HalfOpen, HalfOpen => { Successful => Closed, - Unsuccessful => Open [SetupTimer], + Unsuccessful => Open [SetupTimer] } } ``` This code sample: -* Defines a state machine called `CircuitBreaker`; +* Defines a state machine called `circuit_breaker`; * Derives the `Debug` trait for it (the `derive` section is optional); -* Adds repr(C) support to generated code for better FFI compatability - (the `repr_c` section is optional and defaults to false); * Sets the initial state of this state machine to `Closed`; * Defines state transitions. For example: on receiving the `Successful` input when in the `HalfOpen` state, the machine must move to the `Closed` @@ -84,56 +81,40 @@ This code sample: This state machine can be used as follows: -```rust +```rust,ignore // Initialize the state machine. The state is `Closed` now. -let mut machine: StateMachine<CircuitBreaker> = StateMachine::new(); +let mut machine = circuit_breaker::StateMachine::new(); // Consume the `Successful` input. No state transition is performed. -let _ = machine.consume(&CircuitBreakerInput::Successful); +let _ = machine.consume(&circuit_breaker::Input::Successful); // Consume the `Unsuccesful` input. The machine is moved to the `Open` // state. The output is `SetupTimer`. -let output = machine.consume(&CircuitBreakerInput::Unsuccessful).unwrap(); +let output = machine.consume(&circuit_breaker::Input::Unsuccessful).unwrap(); // Check the output -if let Some(CircuitBreakerOutput::SetupTimer) = output { +if let Some(circuit_breaker::Output::SetupTimer) = output { // Set up the timer... } // Check the state -if let CircuitBreakerState::Open = machine.state() { +if let circuit_breaker::State::Open = machine.state() { // Do something... } ``` -As you can see, the following entities are generated: - -* An empty structure `CircuitBreaker` that implements the `StateMachineImpl` - trait. -* Enums `CircuitBreakerState`, `CircuitBreakerInput` and - `CircuitBreakerOutput` that represent the state, the input alphabet and - the output alphabet respectively. - -Note that if there is no outputs in the specification, the output alphabet -is set to `()`. The set of states and the input alphabet must be non-empty -sets. - -#### Visibility +The following entities are generated: -You can specify visibility like this: - -```rust -state_machine! { - pub CircuitBreaker(Closed) +* An empty structure `circuit_breaker::Impl` that implements the + `StateMachineImpl` trait. +* Enums `circuit_breaker::State`, `circuit_breaker::Input` and + `circuit_breaker::Output` that represent the state, the input alphabet and the + output alphabet respectively. +* Type alias `circuit_breaker::StateMachine` that expands to +`StateMachine<circuit_breaker::Impl>`. - Closed(Unsuccessful) => Open [SetupTimer], - Open(TimerTriggered) => HalfOpen, - HalfOpen => { - Successful => Closed, - Unsuccessful => Open [SetupTimer], - } -} -``` +Note that if there is no outputs in the specification, the output alphabet is an +empty enum and due to technical limitations of many Rust attributes, no +attributes (e.g. `derive`, `repr`) are applied to it. -Note that the default visibility is private just like for any structure. The -specified visibility will apply to all structures and enums generated by the -macro. +Within the `state_machine` macro you must define at least one state +transition. ### Without DSL @@ -148,8 +129,4 @@ wrappers (for now there is only `StateMachine`). You can see an example of the Circuit Breaker state machine in the [project repository][repo]. -[repo]: https://github.com/eugene-babichenko/rust-fsm/blob/master/rust-fsm/tests/circuit_breaker.rs -[docs-badge]: https://docs.rs/rust-fsm/badge.svg -[docs-link]: https://docs.rs/rust-fsm -[crate-badge]: https://img.shields.io/crates/v/rust-fsm.svg -[crate-link]: https://crates.io/crates/rust-fsm +[repo]: https://github.com/eugene-babichenko/rust-fsm/blob/master/tests/circuit_breaker.rs |