1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99


/// Error type that will be returned if an error during the message polling or pushing occurred.
/// It will indicate what the cause for the error was and return the original message in the push
/// case.
#[derive(Debug)]
#[non_exhaustive]
pub enum MessageError<T> {
    /// Will be returned if the state is not active. If it originated during a push, the rejected messaged will be returned with the error.
    StateIsNotActive(T),
}

pub mod __protected {
    use crate::message::MessageError;
    use crate::__protected::StateMachine;
    use crate::{ReturnMessage, ReceiveMessage, State};

    /// The PushMessage trait implementation will be generated by the add_message! macro and is used
    /// to send messages into the state machine where they will then be forwarded to the correct
    /// state.
    pub trait PushMessage<TargetState, Message>: StateMachine
        where TargetState: State + ReceiveMessage<Message>
    {
        /// This will call the receive_message function of ``` FooState ``` if it implemented the ReceiveMessage
        /// trait for message 'FooMessage' and it has been declared to do so with the add_message! macro.
        ///```ignore
        /// use sfsm_base::PushMessage;
        /// let some_message = 2u32;
        /// PushMessage::<FooState, FooMessage>::push_message(&mut sfsm, some_message);
        ///```
        fn push_message(&mut self, message: Message) -> Result<(), MessageError<Message>>;
    }

    /// The PollMessage trait implementation will be generated by the add_message! macro and is used
    /// to return messages from states.
    pub trait PollMessage<TargetState, Message>: StateMachine
        where TargetState: State + ReturnMessage<Message>
    {
        /// This will call the return_message function of ``` FooState ``` if it implemented the ReturnMessage
        /// trait for message 'FooMessage' and it has been declared to do so with the add_message! macro.
        ///```ignore
        /// use sfsm_base::PollMessage;
        /// let some_message = PollMessage::<FooState, FooMessage>::poll_message(&mut sfsm);
        ///```
        fn poll_message(&mut self) -> Result<Option<Message>, MessageError<()>>;
    }
}


/// Trait to handle an incoming message
///
/// Implement this trait for a state that can receive a message according to the add_message
/// definition.
/// Note: for the state to actually be able to receive a message, the message has to be added with
/// the add_message!
pub trait ReceiveMessage<Message> {
    /// Receive a message when a message for the corresponding state is pushed into the state
    /// machine
    ///
    /// ```rust
    /// # use sfsm_base::message::ReceiveMessage;
    /// # #[derive(Debug)]
    /// # struct Message {};
    /// # struct State {};
    /// #
    /// # impl ReceiveMessage<Message> for State {
    ///     fn receive_message(&mut self, message: Message) {
    ///         println!("Got a message {:?}", message);
    ///     }
    /// # }
    /// ```
    fn receive_message(&mut self, message: Message);
}

/// Trait to handle an outgoing message
///
/// Implement this trait for a state that can return a message according to the add_message
/// definition.
/// Note: for the state to actually be able to return a message, the message has to be added with
/// the add_message! macro.
pub trait ReturnMessage<Message> {
    /// Return a message from a state when polled
    ///
    /// ```rust
    /// # use sfsm_base::message::ReturnMessage;
    /// # struct Message {};
    /// # struct State {};
    /// #
    /// # impl ReturnMessage<Message> for State {
    ///     fn return_message(&mut self) -> Option<Message> {
    ///         let message = Message{};
    ///         println!("Returning a message when polled");
    ///         return Some(message);
    ///     }
    /// # }
    ///
    /// ```
    fn return_message(&mut self) -> Option<Message>;
}