State Machine with a clear interface

Hello rustaceans!

I have been inspired by a few articles I have read and some recent projects that would benefit from the use of State Machines.

So I have decided to try my hand at writing a few.

The design goals of this one (Github Link) were to have:

  • Transitions that are checked at compile time
  • States wrapped in an enum for flexibility
  • Clear and easy to use interface
  • Linear State Machine with an Error State (Safety Cut Out State - accessible from any other state)

Transitions checked at compile time

(inspired by Pretty State Machine Pattern - Blog Post)

Example:

impl From<GlorifiedKettle<Heating>> for GlorifiedKettle<Emptying> {
    fn from(val: GlorifiedKettle<Heating>) -> GlorifiedKettle<Emptying> {
        GlorifiedKettle {
            current_level: val.current_level,
            current_temperature: val.current_temperature,
            state: Emptying { end_level: EMPTY },
        }
    }
}

States wrapped in an enum for flexibility

let mut state = States::Filling(GlorifiedKettle::new());

Clear and easy to use interface

The main() function can call the state machine using

state.run() & check if the end condition for the transition is met using state.is_end_condition_met() and then transition state.step()

Linear State Machine with an Error State

Error state can be entered from any state (if an Error condition is encountered) or could be integrated into an ISR. The transition is called by state.error()

Feedback

I am quite content with how it's panned out. I can integrate it and extend it for a few of my projects as is.

There are a few sections I am wondering if they can be improved. It does seem a bit verbose at times (with the From() impl's and the enum State impl wrappers used to call the underlying state methods)

Any feedback would be welcome :slight_smile:

2 Likes

I'm confused. Are you asking for feedback on the blog, on your idea / example, or something else? From the description I expected a link to a library or to the Playground. If there is a link in there I apologize for not being able to find it.

Excuse me, I hadn't added the Github link :sweat_smile:

Yes, I am asking for feedback on my implementation, as I quite happy with the ease of use but there are sections that I am wondering if they could be improved. In all, I am open to any kind of feedback :slight_smile:

1 Like