bacnet_types/
network_number.rs1#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
5pub struct NetworkNumber {
6 number: u16,
7 quality: u8,
8}
9impl NetworkNumber {
10 pub const fn configured(number: u16) -> Option<Self> {
13 if number == u16::MAX {
14 return None;
15 }
16 Some(Self {
17 number,
18 quality: if number == 0 { 0 } else { 3 },
19 })
20 }
21 pub fn snapshot(self) -> (u16, u8) {
23 (self.number, self.quality)
24 }
25 pub fn observe(&mut self, number: u16, flag: u8) -> Observation {
27 if number == 0 || number == u16::MAX || flag > 1 {
28 return Observation::Ignored;
29 }
30 if self.quality == 3 {
31 return if flag == 1 && number != self.number {
32 Observation::ConfiguredConflict
33 } else {
34 Observation::Ignored
35 };
36 }
37 if flag == 1 || self.quality < 2 {
38 self.number = number;
39 self.quality = if flag == 1 { 2 } else { 1 };
40 Observation::Applied
41 } else {
42 Observation::Ignored
43 }
44 }
45}
46#[derive(Clone, Copy, Debug, PartialEq, Eq)]
48pub enum Observation {
49 Applied,
51 Ignored,
53 ConfiguredConflict,
55}
56#[cfg(test)]
57mod tests {
58 use super::*;
59 #[test]
60 fn network_number_quality_precedence_and_numeric_policy() {
61 assert_eq!(NetworkNumber::configured(u16::MAX), None);
62 let mut state = NetworkNumber::default();
63 assert_eq!(state.snapshot(), (0, 0));
64 for (number, flag, expected) in [
65 (10, 0, (10, 1)),
66 (11, 0, (11, 1)),
67 (11, 1, (11, 2)),
68 (11, 0, (11, 2)),
69 (12, 0, (11, 2)),
70 (12, 1, (12, 2)),
71 (0, 1, (12, 2)),
72 (65535, 1, (12, 2)),
73 (15, 2, (12, 2)),
74 (65534, 1, (65534, 2)),
75 (1, 1, (1, 2)),
76 ] {
77 state.observe(number, flag);
78 assert_eq!(state.snapshot(), expected);
79 }
80 let mut configured = NetworkNumber::configured(17).unwrap();
81 assert_eq!(configured.observe(18, 1), Observation::ConfiguredConflict);
82 configured.observe(19, 0);
83 assert_eq!(configured.snapshot(), (17, 3));
84 assert_eq!(NetworkNumber::configured(0).unwrap().snapshot(), (0, 0));
85 }
86}