1use core::cmp::Ordering;
2
3#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub enum ClockAccuracy {
8 Reserved,
10 PS1,
12 PS2_5,
14 PS10,
16 PS25,
18 PS100,
20 PS250,
22 NS1,
24 NS2_5,
26 NS10,
28 NS25,
30 NS100,
32 NS250,
34 US1,
36 US2_5,
38 US10,
40 US25,
42 US100,
44 US250,
46 MS1,
48 MS2_5,
50 MS10,
52 MS25,
54 MS100,
56 MS250,
58 S1,
60 S10,
62 SGT10,
64 ProfileSpecific(u8),
66 #[default]
68 Unknown,
69}
70
71impl ClockAccuracy {
72 #[must_use]
74 pub fn to_primitive(self) -> u8 {
75 match self {
76 Self::Reserved => 0x00,
77 Self::PS1 => 0x17,
78 Self::PS2_5 => 0x18,
79 Self::PS10 => 0x19,
80 Self::PS25 => 0x1a,
81 Self::PS100 => 0x1b,
82 Self::PS250 => 0x1c,
83 Self::NS1 => 0x1d,
84 Self::NS2_5 => 0x1e,
85 Self::NS10 => 0x1f,
86 Self::NS25 => 0x20,
87 Self::NS100 => 0x21,
88 Self::NS250 => 0x22,
89 Self::US1 => 0x23,
90 Self::US2_5 => 0x24,
91 Self::US10 => 0x25,
92 Self::US25 => 0x26,
93 Self::US100 => 0x27,
94 Self::US250 => 0x28,
95 Self::MS1 => 0x29,
96 Self::MS2_5 => 0x2a,
97 Self::MS10 => 0x2b,
98 Self::MS25 => 0x2c,
99 Self::MS100 => 0x2d,
100 Self::MS250 => 0x2e,
101 Self::S1 => 0x2f,
102 Self::S10 => 0x30,
103 Self::SGT10 => 0x31,
104 Self::ProfileSpecific(value) => 0x80 + value,
105 Self::Unknown => 0xfe,
106 }
107 }
108
109 #[must_use]
111 pub fn from_primitive(value: u8) -> Self {
112 match value {
113 0x00..=0x16 | 0x32..=0x7f | 0xff => Self::Reserved,
114 0x17 => Self::PS1,
115 0x18 => Self::PS2_5,
116 0x19 => Self::PS10,
117 0x1a => Self::PS25,
118 0x1b => Self::PS100,
119 0x1c => Self::PS250,
120 0x1d => Self::NS1,
121 0x1e => Self::NS2_5,
122 0x1f => Self::NS10,
123 0x20 => Self::NS25,
124 0x21 => Self::NS100,
125 0x22 => Self::NS250,
126 0x23 => Self::US1,
127 0x24 => Self::US2_5,
128 0x25 => Self::US10,
129 0x26 => Self::US25,
130 0x27 => Self::US100,
131 0x28 => Self::US250,
132 0x29 => Self::MS1,
133 0x2a => Self::MS2_5,
134 0x2b => Self::MS10,
135 0x2c => Self::MS25,
136 0x2d => Self::MS100,
137 0x2e => Self::MS250,
138 0x2f => Self::S1,
139 0x30 => Self::S10,
140 0x31 => Self::SGT10,
141 0x80..=0xfd => Self::ProfileSpecific(value - 0x80),
142 0xfe => ClockAccuracy::Unknown,
143 }
144 }
145}
146
147impl PartialOrd for ClockAccuracy {
148 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
149 Some(self.cmp(other))
150 }
151}
152
153impl Ord for ClockAccuracy {
154 fn cmp(&self, other: &Self) -> Ordering {
155 self.to_primitive().cmp(&other.to_primitive())
156 }
157}
158
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn network_protocol_values() {
165 for i in 0..u8::MAX {
166 let protocol = ClockAccuracy::from_primitive(i);
167 if !matches!(protocol, ClockAccuracy::Reserved) {
168 assert_eq!(protocol.to_primitive(), i);
169 }
170 }
171
172 assert_eq!(ClockAccuracy::ProfileSpecific(5).to_primitive(), 0x85);
173 }
174
175 #[test]
176 fn ordering() {
177 let a = ClockAccuracy::PS1;
179 let b = ClockAccuracy::PS10;
180
181 assert_eq!(a.cmp(&b), Ordering::Less);
182 }
183}