sfsm_base/lib.rs
1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(test), no_std)]
3
4/// Contains definitions for a state machine that contains error handling mechanisms
5pub mod fallible;
6
7/// Contains definitions used by a state machine without any error handling support
8pub mod non_fallible;
9
10/// Contains definitions and code for the messaging system
11pub mod message;
12
13/// Enum used to indicate to the guard function if the transition should transit to the
14/// next state or remain in the current one.
15/// ```rust
16/// # use sfsm_base::non_fallible::{Transition, State};
17/// # use sfsm_base::TransitGuard;
18/// # struct FooState;
19/// # struct BarState;
20/// # impl State for FooState {};
21/// # impl Into<BarState> for FooState {
22/// # fn into(self) -> BarState {
23/// # BarState{}
24/// # }
25/// # }
26///
27/// # impl Transition<BarState> for FooState {
28/// fn guard(&self) -> TransitGuard {
29/// let foo = 0;
30/// if foo == 0 {
31/// TransitGuard::Remain
32/// } else {
33/// TransitGuard::Transit
34/// }
35/// }
36/// # }
37/// ```
38#[derive(PartialEq)]
39pub enum TransitGuard {
40 /// Remains in the current state
41 Remain,
42 /// Transits into the next state
43 Transit
44}
45
46/// Implements from<bool> trait for use of use.
47/// This allows to transit by returning true. Which simplify the code since it allows to return the
48/// TransitGuard from a simple comparison.
49/// ```rust
50/// # use sfsm_base::non_fallible::{Transition, State};
51/// # use sfsm_base::TransitGuard;
52/// # struct FooState;
53/// # struct BarState;
54/// # impl State for FooState {};
55/// # impl Into<BarState> for FooState {
56/// # fn into(self) -> BarState {
57/// # BarState{}
58/// # }
59/// # }
60///
61/// # impl Transition<BarState> for FooState {
62/// fn guard(&self) -> TransitGuard {
63/// let foo = 0;
64/// (foo == 0).into() // Returns TransitGuard::Transit
65/// }
66/// # }
67/// ```
68impl From<bool> for TransitGuard {
69 fn from(transit: bool) -> Self {
70 if transit {
71 TransitGuard::Transit
72 } else {
73 TransitGuard::Remain
74 }
75 }
76}
77
78/// Contains traits that are used to interact with the state machine but should not be implemented
79/// manually. All necessary implementations will be created by the macros.
80pub mod __protected {
81
82 /// Trait that will be implemented for the state machine.
83 pub trait StateMachine {
84 /// The initial state of the state machine.
85 type InitialState;
86
87 /// The returned error. This is also implemented in non fallible state machines,
88 /// but will be ignore as there is no case this error could occur.
89 type Error;
90
91 /// The generator enum containing all states
92 type StatesEnum;
93
94 /// Start function that must be called first. It populates the internal enum with the
95 /// initial state. If step is called before start, the state machine will return an error.
96 fn start(&mut self, state: Self::InitialState) -> Result<(), Self::Error>;
97
98 /// The step function that executes all states and transitions.
99 fn step(&mut self) -> Result<(), Self::Error>;
100
101 /// If desired, the state machine can be stopped. When doing so, the internal states enum
102 /// is returned.
103 fn stop(self) -> Result<Self::StatesEnum, Self::Error>;
104
105 /// Peek the internal states enum.
106 fn peek_state(&self) -> &Self::StatesEnum;
107 }
108
109 /// An implementation of this trait will be generated for every state.
110 /// This is can be used to test if the state machine is in a desired state.
111 pub trait IsState<State>: StateMachine {
112 /// The method must be called with the turbo fish syntax as otherwise Rust cannot figure out
113 /// which implementation to call. To check if the state machine is in a given state call:
114 ///
115 /// ```ignore
116 /// let is_in_state: bool = IsState::<State>::is_state(&sfsm);
117 /// ```
118 fn is_state(&self) -> bool;
119 }
120}
121
122pub use __protected::*;
123pub use non_fallible::*;
124pub use fallible::*;
125pub use message::*;
126pub use message::__protected::*;
127
128