Skip to main content

basic/
basic.rs

1//! Basic lifecycle.
2//!
3//! A small example that moves through Ready, Active, and Safe.
4//! Events drive the transitions. The machine returns decisions as data.
5
6#![allow(clippy::print_stdout, clippy::enum_glob_use)]
7
8use ready_active_safe::prelude::*;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11enum Mode {
12    Ready,
13    Active,
14    Safe,
15}
16
17impl core::fmt::Display for Mode {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        write!(f, "{self:?}")
20    }
21}
22
23#[derive(Debug)]
24enum Event {
25    Initialize,
26    Start,
27    Fault,
28}
29
30#[derive(Debug, PartialEq)]
31enum Command {
32    RunDiagnostics,
33    BeginProcessing,
34    FlushBuffers,
35    NotifyOperator,
36}
37
38struct Controller;
39
40impl Machine for Controller {
41    type Mode = Mode;
42    type Event = Event;
43    type Command = Command;
44
45    fn initial_mode(&self) -> Mode {
46        Mode::Ready
47    }
48
49    fn on_event(
50        &self,
51        mode: &Self::Mode,
52        event: &Self::Event,
53    ) -> Decision<Self::Mode, Self::Command> {
54        use Command::*;
55        use Event::*;
56        use Mode::*;
57
58        match (mode, event) {
59            (Ready, Initialize) => stay().emit(RunDiagnostics),
60            (Ready, Start) => transition(Active).emit(BeginProcessing),
61            (Active, Fault) => transition(Safe).emit_all([FlushBuffers, NotifyOperator]),
62            _ => ignore(),
63        }
64    }
65}
66
67fn main() {
68    let controller = Controller;
69    let mut mode = controller.initial_mode();
70
71    let events = [Event::Initialize, Event::Start, Event::Fault];
72
73    for event in &events {
74        let decision = controller.decide(&mode, event);
75        println!("{mode:?} + {event:?} => {decision}");
76
77        let (next_mode, commands) = decision.apply(mode);
78        if !commands.is_empty() {
79            println!("  commands: {commands:?}");
80        }
81
82        mode = next_mode;
83    }
84
85    assert_eq!(mode, Mode::Safe);
86}