zencan_common/
nmt.rs

1//! Definitions for the NMT protocol
2
3/// Possible NMT states for a node
4#[derive(Copy, Clone, Debug, PartialEq)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6#[repr(u8)]
7pub enum NmtState {
8    /// Bootup
9    ///
10    /// A node never remains in this state, as all nodes should transition automatically into PreOperational
11    Bootup = 0,
12    /// Node has been stopped
13    Stopped = 4,
14    /// Normal operational state
15    Operational = 5,
16    /// Node is awaiting command to enter operation
17    PreOperational = 127,
18}
19
20impl core::fmt::Display for NmtState {
21    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22        match self {
23            NmtState::Bootup => write!(f, "Bootup"),
24            NmtState::Stopped => write!(f, "Stopped"),
25            NmtState::Operational => write!(f, "Operational"),
26            NmtState::PreOperational => write!(f, "PreOperational"),
27        }
28    }
29}
30
31#[derive(Clone, Copy, Debug)]
32/// An error for [`NmtState::try_from()`]
33pub struct InvalidNmtStateError(pub u8);
34
35impl TryFrom<u8> for NmtState {
36    type Error = InvalidNmtStateError;
37
38    /// Attempt to convert a u8 to an NmtState enum
39    ///
40    /// Fails with BadNmtStateError if value is not a valid state
41    fn try_from(value: u8) -> Result<Self, Self::Error> {
42        use NmtState::*;
43        match value {
44            x if x == Bootup as u8 => Ok(Bootup),
45            x if x == Stopped as u8 => Ok(Stopped),
46            x if x == Operational as u8 => Ok(Operational),
47            x if x == PreOperational as u8 => Ok(PreOperational),
48            _ => Err(InvalidNmtStateError(value)),
49        }
50    }
51}