finny/fsm/
events.rs

1use crate::{FsmBackend, FsmEventQueue, FsmEventQueueSender, lib::*};
2
3/// The internal event type that also allows stopping or starting the machine.
4#[derive(Clone)]
5pub enum FsmEvent<E, T> {
6    Start,
7    Stop,
8    Timer(T),
9    Event(E)
10}
11
12impl<E, T> From<E> for FsmEvent<E, T> {
13    fn from(event: E) -> Self {
14        FsmEvent::Event(event)
15    }
16}
17
18impl<E, T> Debug for FsmEvent<E, T> where E: Debug, T: Debug {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            FsmEvent::Start => f.write_str("Fsm::Start"),
22            FsmEvent::Stop => f.write_str("Fsm::Stop"),
23            FsmEvent::Timer(t) => f.write_fmt(format_args!("Fsm::Timer({:?})", t)),
24            FsmEvent::Event(ev) => ev.fmt(f)
25        }
26    }
27}
28
29impl<E, T> AsRef<str> for FsmEvent<E, T> where E: AsRef<str> {
30    fn as_ref(&self) -> &str {
31        match self {
32            FsmEvent::Start => "Fsm::Start",
33            FsmEvent::Stop => "Fsm::Stop",
34            FsmEvent::Timer(_) => "Fsm::Timer",
35            FsmEvent::Event(e) => e.as_ref()
36        }
37    }
38}
39
40impl<E, T> FsmEvent<E, T> {
41    pub fn to_sub_fsm<FSub>(self) -> FsmEvent<<FSub as FsmBackend>::Events, <FSub as FsmBackend>::Timers>
42        where FSub: FsmBackend,
43        <FSub as FsmBackend>::Timers: From<T>,
44        <FSub as FsmBackend>::Timers: From<E>
45    {
46        match self {
47            FsmEvent::Start => FsmEvent::Start,
48            FsmEvent::Stop => FsmEvent::Stop,
49            FsmEvent::Timer(t) => {
50                FsmEvent::Timer(t.into())
51            }
52            FsmEvent::Event(ev) => {
53                FsmEvent::Timer(ev.into())
54            }
55        }
56    }
57}
58
59
60pub type FsmRegionId = usize;
61
62/// The context that is given to all of the guards and actions.
63pub struct EventContext<'a, TFsm, Q> where TFsm: FsmBackend, Q: FsmEventQueueSender<TFsm> {
64    pub context: &'a mut TFsm::Context,
65    pub queue: &'a mut Q,
66    pub region: FsmRegionId
67}
68
69impl<'a, TFsm, Q> Deref for EventContext<'a, TFsm, Q> where TFsm: FsmBackend, Q: FsmEventQueueSender<TFsm>
70{
71    type Target = <TFsm as FsmBackend>::Context;
72
73    fn deref(&self) -> &Self::Target {
74        self.context
75    }
76}
77
78impl<'a, TFsm: FsmBackend, Q> DerefMut for EventContext<'a, TFsm, Q> where TFsm: FsmBackend, Q: FsmEventQueueSender<TFsm> {
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        self.context
81    }
82}