umsh_ulcp/
alert.rs

1//! The locate-alert enumeration (`PROP_ALERT`).
2//!
3//! The property value is a single PUI naming what the device is currently
4//! doing to draw attention to where it physically is. What that consists
5//! of is board-defined: a buzzer, an indicator LED, and a display all
6//! satisfy the same value.
7
8/// `PROP_ALERT` states.
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
10pub enum AlertState {
11    /// `ALERT_NONE` — the nominal state.
12    #[default]
13    None = 0,
14    /// `ALERT_LOCATE` — make the device as conspicuous as its hardware
15    /// allows until the alert is cleared.
16    Locate = 1,
17}
18
19impl AlertState {
20    /// The wire code for this state.
21    pub const fn code(self) -> u32 {
22        self as u32
23    }
24
25    /// Strict conversion from a decoded wire code.
26    pub const fn from_code(code: u32) -> Option<Self> {
27        match code {
28            0 => Some(Self::None),
29            1 => Some(Self::Locate),
30            _ => None,
31        }
32    }
33
34    /// Whether an alert is in progress.
35    pub const fn is_active(self) -> bool {
36        matches!(self, Self::Locate)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn codes_round_trip_strictly() {
46        assert_eq!(AlertState::from_code(0), Some(AlertState::None));
47        assert_eq!(AlertState::from_code(1), Some(AlertState::Locate));
48        assert_eq!(AlertState::from_code(2), None);
49        assert_eq!(AlertState::None.code(), 0);
50        assert_eq!(AlertState::Locate.code(), 1);
51    }
52
53    #[test]
54    fn default_is_nominal() {
55        assert_eq!(AlertState::default(), AlertState::None);
56        assert!(!AlertState::default().is_active());
57        assert!(AlertState::Locate.is_active());
58    }
59}