1use crate::err::ip::IpDscpUnknownValueError;
2
3use super::IpDscp;
4
5#[derive(Copy, Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
13pub enum IpDscpKnown {
14 ClassSelector0 = 0b0000_0000,
16
17 ClassSelector1 = 0b0000_1000,
19
20 ClassSelector2 = 0b0001_0000,
22
23 ClassSelector3 = 0b0001_1000,
25
26 ClassSelector4 = 0b0010_0000,
28
29 ClassSelector5 = 0b0010_1000,
31
32 ClassSelector6 = 0b0011_0000,
34
35 ClassSelector7 = 0b0011_1000,
37
38 AfGroup11 = 0b0000_1010,
40
41 AfGroup12 = 0b0000_1100,
43
44 AfGroup13 = 0b0000_1110,
46
47 AfGroup21 = 0b0001_0010,
49
50 AfGroup22 = 0b0001_0100,
52
53 AfGroup23 = 0b0001_0110,
55
56 AfGroup31 = 0b0001_1010,
58
59 AfGroup32 = 0b0001_1100,
61
62 AfGroup33 = 0b0001_1110,
64
65 AfGroup41 = 0b0010_0010,
67
68 AfGroup42 = 0b0010_0100,
70
71 AfGroup43 = 0b0010_0110,
73
74 ExpeditedForwarding = 0b_0010_1110,
76
77 VoiceAdmit = 0b0010_1100,
79
80 LowerEffort = 0b0000_0001,
82 }
84
85impl IpDscpKnown {
86 pub const fn try_from_ip_dscp(value: IpDscp) -> Result<IpDscpKnown, IpDscpUnknownValueError> {
90 match value {
91 IpDscp::CS0 => Ok(IpDscpKnown::ClassSelector0),
92 IpDscp::CS1 => Ok(IpDscpKnown::ClassSelector1),
93 IpDscp::CS2 => Ok(IpDscpKnown::ClassSelector2),
94 IpDscp::CS3 => Ok(IpDscpKnown::ClassSelector3),
95 IpDscp::CS4 => Ok(IpDscpKnown::ClassSelector4),
96 IpDscp::CS5 => Ok(IpDscpKnown::ClassSelector5),
97 IpDscp::CS6 => Ok(IpDscpKnown::ClassSelector6),
98 IpDscp::CS7 => Ok(IpDscpKnown::ClassSelector7),
99 IpDscp::AF11 => Ok(IpDscpKnown::AfGroup11),
100 IpDscp::AF12 => Ok(IpDscpKnown::AfGroup12),
101 IpDscp::AF13 => Ok(IpDscpKnown::AfGroup13),
102 IpDscp::AF21 => Ok(IpDscpKnown::AfGroup21),
103 IpDscp::AF22 => Ok(IpDscpKnown::AfGroup22),
104 IpDscp::AF23 => Ok(IpDscpKnown::AfGroup23),
105 IpDscp::AF31 => Ok(IpDscpKnown::AfGroup31),
106 IpDscp::AF32 => Ok(IpDscpKnown::AfGroup32),
107 IpDscp::AF33 => Ok(IpDscpKnown::AfGroup33),
108 IpDscp::AF41 => Ok(IpDscpKnown::AfGroup41),
109 IpDscp::AF42 => Ok(IpDscpKnown::AfGroup42),
110 IpDscp::AF43 => Ok(IpDscpKnown::AfGroup43),
111 IpDscp::EF => Ok(IpDscpKnown::ExpeditedForwarding),
112 IpDscp::VOICE_ADMIT => Ok(IpDscpKnown::VoiceAdmit),
113 IpDscp::LOWER_EFFORT => Ok(IpDscpKnown::LowerEffort),
114 value => Err(IpDscpUnknownValueError {
115 value: value.value(),
116 }),
117 }
118 }
119}
120
121impl TryFrom<IpDscp> for IpDscpKnown {
122 type Error = crate::err::ip::IpDscpUnknownValueError;
123
124 fn try_from(value: IpDscp) -> Result<Self, Self::Error> {
125 Self::try_from_ip_dscp(value)
126 }
127}
128
129impl From<IpDscpKnown> for u8 {
130 fn from(value: IpDscpKnown) -> Self {
131 value as u8
132 }
133}
134
135impl From<IpDscpKnown> for IpDscp {
136 fn from(value: IpDscpKnown) -> Self {
137 unsafe { IpDscp::new_unchecked(value as u8) }
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146 use crate::{err::ip::IpDscpUnknownValueError, IpDscp};
147
148 #[test]
149 fn try_from_ip_dscp() {
150 {
152 use IpDscpKnown::*;
153 let tests = [
154 (ClassSelector0, 0b0000_0000u8),
155 (ClassSelector1, 0b0000_1000u8),
156 (ClassSelector2, 0b0001_0000u8),
157 (ClassSelector3, 0b0001_1000u8),
158 (ClassSelector4, 0b0010_0000u8),
159 (ClassSelector5, 0b0010_1000u8),
160 (ClassSelector6, 0b0011_0000u8),
161 (ClassSelector7, 0b0011_1000u8),
162 (AfGroup11, 0b0000_1010u8),
163 (AfGroup12, 0b0000_1100u8),
164 (AfGroup13, 0b0000_1110u8),
165 (AfGroup21, 0b0001_0010u8),
166 (AfGroup22, 0b0001_0100u8),
167 (AfGroup23, 0b0001_0110u8),
168 (AfGroup31, 0b0001_1010u8),
169 (AfGroup32, 0b0001_1100u8),
170 (AfGroup33, 0b0001_1110u8),
171 (AfGroup41, 0b0010_0010u8),
172 (AfGroup42, 0b0010_0100u8),
173 (AfGroup43, 0b0010_0110u8),
174 (ExpeditedForwarding, 0b_0010_1110u8),
175 (VoiceAdmit, 0b0010_1100u8),
176 (LowerEffort, 0b0000_0001u8),
177 ];
178 for (expected, value) in tests {
179 let ip_dscp = IpDscp::try_new(value).unwrap();
180 assert_eq!(Ok(expected), IpDscpKnown::try_from_ip_dscp(ip_dscp));
181 assert_eq!(Ok(expected), IpDscpKnown::try_from(ip_dscp));
182 }
183 }
184
185 {
187 let unknown_ranges = [
189 2..=7u8,
190 9..=9u8,
191 11..=11u8,
192 13..=13u8,
193 15..=15u8,
194 17..=17u8,
195 19..=19u8,
196 21..=21u8,
197 23..=23u8,
198 25..=25u8,
199 27..=27u8,
200 29..=29u8,
201 31..=31u8,
202 33..=33u8,
203 35..=35u8,
204 37..=37u8,
205 39..=39u8,
206 41..=43u8,
207 45..=45u8,
208 47..=47u8,
209 49..=55u8,
210 57..=0b0011_1111u8,
211 ];
212 for range in unknown_ranges {
213 for value in range {
214 let ip_dscp = IpDscp::try_new(value).unwrap();
215 assert_eq!(
216 Err(IpDscpUnknownValueError { value }),
217 IpDscpKnown::try_from_ip_dscp(ip_dscp)
218 );
219 assert_eq!(
220 Err(IpDscpUnknownValueError { value }),
221 IpDscpKnown::try_from(ip_dscp)
222 );
223 }
224 }
225 }
226 }
227
228 #[test]
229 fn into_u8_and_ip_dscp() {
230 use IpDscpKnown::*;
231 let tests = [
232 (ClassSelector0, 0b0000_0000u8),
233 (ClassSelector1, 0b0000_1000u8),
234 (ClassSelector2, 0b0001_0000u8),
235 (ClassSelector3, 0b0001_1000u8),
236 (ClassSelector4, 0b0010_0000u8),
237 (ClassSelector5, 0b0010_1000u8),
238 (ClassSelector6, 0b0011_0000u8),
239 (ClassSelector7, 0b0011_1000u8),
240 (AfGroup11, 0b0000_1010u8),
241 (AfGroup12, 0b0000_1100u8),
242 (AfGroup13, 0b0000_1110u8),
243 (AfGroup21, 0b0001_0010u8),
244 (AfGroup22, 0b0001_0100u8),
245 (AfGroup23, 0b0001_0110u8),
246 (AfGroup31, 0b0001_1010u8),
247 (AfGroup32, 0b0001_1100u8),
248 (AfGroup33, 0b0001_1110u8),
249 (AfGroup41, 0b0010_0010u8),
250 (AfGroup42, 0b0010_0100u8),
251 (AfGroup43, 0b0010_0110u8),
252 (ExpeditedForwarding, 0b_0010_1110u8),
253 (VoiceAdmit, 0b0010_1100u8),
254 (LowerEffort, 0b0000_0001u8),
255 ];
256 for (input, expected) in tests {
257 assert_eq!(expected, u8::from(input));
258 assert_eq!(IpDscp::try_new(expected).unwrap(), IpDscp::from(input));
259 }
260 }
261}