pub trait StateMachine<State, Input> {
// Required methods
fn current_state(&self) -> State;
fn consume(&self, input: Input) -> State;
fn peek(&self, input: Input) -> State;
fn reset(&self) -> State;
fn set(&self, new_state: State);
}
Expand description
The trait is representing the basic operation for the state machine.
It includes getting its current state, transition to the next state,
resetting its current state to initial state and setting particular state forcibly.
BasicStateMachine
is a good example to implement it.
Of course, you can build your own state machine by using this trait.
Required Methods§
Sourcefn current_state(&self) -> State
fn current_state(&self) -> State
Returns the current state of the state machine.
§Example
use statemachine_rs::machine::{
builder::BasicStateMachineBuilder, builder::StateMachineBuilder, StateMachine,
};
#[derive(Clone, Debug, PartialEq)]
enum ButtonState {
On,
Off,
}
#[allow(dead_code)]
enum Input {
Press,
}
let sm = BasicStateMachineBuilder::start()
.initial_state(ButtonState::Off)
.transition(|state, input| match (state, input) {
(ButtonState::On, Input::Press) => ButtonState::Off,
(ButtonState::Off, Input::Press) => ButtonState::On,
})
.build()
.unwrap();
assert_eq!(ButtonState::Off, sm.current_state());
Sourcefn consume(&self, input: Input) -> State
fn consume(&self, input: Input) -> State
Returns the result of state transition according to input
and
the definition of transition function.
§Example
use statemachine_rs::machine::{
builder::BasicStateMachineBuilder, builder::StateMachineBuilder, StateMachine,
};
#[derive(Clone, Debug, PartialEq)]
enum ButtonState {
On,
Off,
}
enum Input {
Press,
}
let sm = BasicStateMachineBuilder::start()
.initial_state(ButtonState::Off)
.transition(|state, input| match (state, input) {
(ButtonState::On, Input::Press) => ButtonState::Off,
(ButtonState::Off, Input::Press) => ButtonState::On,
})
.build()
.unwrap();
assert_eq!(ButtonState::Off, sm.current_state());
assert_eq!(ButtonState::On, sm.consume(Input::Press));
Sourcefn peek(&self, input: Input) -> State
fn peek(&self, input: Input) -> State
Returns the next state from the current state but the state machine retains in its current state.
§Example
use statemachine_rs::machine::{
builder::BasicStateMachineBuilder, builder::StateMachineBuilder, StateMachine,
};
#[derive(Clone, Debug, PartialEq)]
enum ButtonState {
On,
Off,
}
enum Input {
Press,
}
let sm = BasicStateMachineBuilder::start()
.initial_state(ButtonState::Off)
.transition(|state, input| match (state, input) {
(ButtonState::On, Input::Press) => ButtonState::Off,
(ButtonState::Off, Input::Press) => ButtonState::On,
})
.build()
.unwrap();
assert_eq!(ButtonState::Off, sm.current_state());
assert_eq!(ButtonState::On, sm.peek(Input::Press));
assert_eq!(ButtonState::Off, sm.current_state());
Sourcefn reset(&self) -> State
fn reset(&self) -> State
Resets the current state to the initial state.
§Example
use statemachine_rs::machine::{
builder::BasicStateMachineBuilder, builder::StateMachineBuilder, StateMachine,
};
#[derive(Clone, Debug, PartialEq)]
enum ButtonState {
On,
Off,
}
enum Input {
Press,
}
let sm = BasicStateMachineBuilder::start()
.initial_state(ButtonState::Off)
.transition(|state, input| match (state, input) {
(ButtonState::On, Input::Press) => ButtonState::Off,
(ButtonState::Off, Input::Press) => ButtonState::On,
})
.build()
.unwrap();
assert_eq!(ButtonState::Off, sm.current_state());
assert_eq!(ButtonState::On, sm.consume(Input::Press));
assert_eq!(ButtonState::Off, sm.reset());
Sourcefn set(&self, new_state: State)
fn set(&self, new_state: State)
Set a new state forcibly to the current state.
§Example
use statemachine_rs::machine::{
builder::BasicStateMachineBuilder, builder::StateMachineBuilder, StateMachine,
};
#[derive(Clone, Debug, PartialEq)]
enum ButtonState {
On,
Off,
Disable,
}
enum Input {
Press,
}
let sm = BasicStateMachineBuilder::start()
.initial_state(ButtonState::Off)
.transition(|state, input| match (state, input) {
(ButtonState::On, Input::Press) => ButtonState::Off,
(ButtonState::Off, Input::Press) => ButtonState::On,
(ButtonState::Disable, Input::Press) => ButtonState::Disable,
})
.build()
.unwrap();
assert_eq!(ButtonState::Off, sm.current_state());
sm.set(ButtonState::Disable);
assert_eq!(ButtonState::Disable, sm.consume(Input::Press));