Skip to main content

simple_someip/protocol/sd/
flags.rs

1const REBOOT_FLAG: u8 = 0b1000_0000;
2const UNICAST_FLAG: u8 = 0b0100_0000;
3
4/// Flags byte in the SD protocol.
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct Flags {
7    reboot: bool,
8    unicast: bool,
9}
10
11impl From<u8> for Flags {
12    /// Only the two most significant bits are used.
13    fn from(value: u8) -> Self {
14        Self {
15            reboot: value & REBOOT_FLAG != 0,
16            unicast: value & UNICAST_FLAG != 0,
17        }
18    }
19}
20
21impl From<Flags> for u8 {
22    fn from(flags: Flags) -> u8 {
23        let mut value = 0;
24        if flags.reboot {
25            value |= REBOOT_FLAG;
26        }
27        if flags.unicast {
28            value |= UNICAST_FLAG;
29        }
30        value
31    }
32}
33
34impl Flags {
35    /// Creates flags with the given reboot and unicast values.
36    #[must_use]
37    pub const fn new(reboot: bool, unicast: bool) -> Self {
38        Self { reboot, unicast }
39    }
40    /// Creates SD flags with unicast always set to `true`.
41    #[must_use]
42    pub const fn new_sd(reboot: bool) -> Self {
43        Self {
44            reboot,
45            unicast: true,
46        }
47    }
48    /// Returns `true` if the reboot flag is set.
49    #[must_use]
50    pub const fn reboot(self) -> bool {
51        self.reboot
52    }
53    /// Returns `true` if the unicast flag is set.
54    #[must_use]
55    pub const fn unicast(self) -> bool {
56        self.unicast
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn new_sd_sets_unicast_true() {
66        let flags = Flags::new_sd(false);
67        assert!(!flags.reboot());
68        assert!(flags.unicast());
69    }
70
71    #[test]
72    fn new_sd_with_reboot_true() {
73        let flags = Flags::new_sd(true);
74        assert!(flags.reboot());
75        assert!(flags.unicast());
76    }
77
78    #[test]
79    fn unicast_accessor() {
80        assert!(Flags::new(false, true).unicast());
81        assert!(!Flags::new(false, false).unicast());
82    }
83
84    #[test]
85    fn roundtrip_both_flags_set() {
86        let flags = Flags::new(true, true);
87        let byte: u8 = flags.into();
88        let back = Flags::from(byte);
89        assert_eq!(flags, back);
90        assert_eq!(byte, 0b1100_0000);
91    }
92
93    #[test]
94    fn roundtrip_no_flags_set() {
95        let flags = Flags::new(false, false);
96        let byte: u8 = flags.into();
97        assert_eq!(byte, 0);
98        let back = Flags::from(byte);
99        assert_eq!(flags, back);
100    }
101}