etherparse/link/
macsec_an.rs1use crate::err::ValueTooBigError;
2
3#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
8pub struct MacsecAn(u8);
9
10impl MacsecAn {
11 pub const ZERO: MacsecAn = MacsecAn(0);
13
14 pub const MAX_U8: u8 = 0b0000_0011;
16
17 #[inline]
42 pub const fn try_new(value: u8) -> Result<MacsecAn, ValueTooBigError<u8>> {
43 use crate::err::ValueType;
44 if value <= MacsecAn::MAX_U8 {
45 Ok(MacsecAn(value))
46 } else {
47 Err(ValueTooBigError {
48 actual: value,
49 max_allowed: MacsecAn::MAX_U8,
50 value_type: ValueType::MacsecAn,
51 })
52 }
53 }
54
55 #[inline]
65 pub const unsafe fn new_unchecked(value: u8) -> MacsecAn {
66 debug_assert!(value <= MacsecAn::MAX_U8);
67 MacsecAn(value)
68 }
69
70 #[inline]
72 pub const fn value(self) -> u8 {
73 self.0
74 }
75}
76
77impl core::fmt::Display for MacsecAn {
78 #[inline]
79 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
80 self.0.fmt(f)
81 }
82}
83
84impl From<MacsecAn> for u8 {
85 #[inline]
86 fn from(value: MacsecAn) -> Self {
87 value.0
88 }
89}
90
91impl TryFrom<u8> for MacsecAn {
92 type Error = ValueTooBigError<u8>;
93
94 #[inline]
95 fn try_from(value: u8) -> Result<Self, Self::Error> {
96 use crate::err::ValueType;
97 if value <= MacsecAn::MAX_U8 {
98 Ok(MacsecAn(value))
99 } else {
100 Err(Self::Error {
101 actual: value,
102 max_allowed: MacsecAn::MAX_U8,
103 value_type: ValueType::MacsecAn,
104 })
105 }
106 }
107}
108
109#[cfg(test)]
110mod test {
111 use super::*;
112 use core::hash::{Hash, Hasher};
113 use proptest::prelude::*;
114 use std::format;
115
116 #[test]
117 fn derived_traits() {
118 {
120 let a = MacsecAn(2);
121 let b = a;
122 assert_eq!(a, b);
123 assert_eq!(a.clone(), a);
124 }
125
126 {
128 let actual: MacsecAn = Default::default();
129 assert_eq!(actual.value(), 0);
130 }
131
132 {
134 let a = MacsecAn(2);
135 assert_eq!(format!("{:?}", a), format!("MacsecAn(2)"));
136 }
137
138 {
140 use core::cmp::Ordering;
141 let a = MacsecAn(2);
142 let b = a;
143 assert_eq!(a.cmp(&b), Ordering::Equal);
144 assert_eq!(a.partial_cmp(&b), Some(Ordering::Equal));
145 }
146
147 {
149 use std::collections::hash_map::DefaultHasher;
150 let a = {
151 let mut hasher = DefaultHasher::new();
152 MacsecAn(2).hash(&mut hasher);
153 hasher.finish()
154 };
155 let b = {
156 let mut hasher = DefaultHasher::new();
157 MacsecAn(2).hash(&mut hasher);
158 hasher.finish()
159 };
160 assert_eq!(a, b);
161 }
162 }
163
164 proptest! {
165 #[test]
166 fn try_new(
167 valid_value in 0..=0b0000_0011u8,
168 invalid_value in 0b0000_0100u8..=u8::MAX
169 ) {
170 use crate::err::{ValueType, ValueTooBigError};
171 assert_eq!(
172 valid_value,
173 MacsecAn::try_new(valid_value).unwrap().value()
174 );
175 assert_eq!(
176 MacsecAn::try_new(invalid_value).unwrap_err(),
177 ValueTooBigError{
178 actual: invalid_value,
179 max_allowed: 0b0000_0011,
180 value_type: ValueType::MacsecAn
181 }
182 );
183 }
184 }
185
186 proptest! {
187 #[test]
188 fn try_from(
189 valid_value in 0..=0b0000_0011u8,
190 invalid_value in 0b0000_0100u8..=u8::MAX
191 ) {
192 use crate::err::{ValueType, ValueTooBigError};
193 {
195 let actual: MacsecAn = valid_value.try_into().unwrap();
196 assert_eq!(actual.value(), valid_value);
197
198 let err: Result<MacsecAn, ValueTooBigError<u8>> = invalid_value.try_into();
199 assert_eq!(
200 err.unwrap_err(),
201 ValueTooBigError{
202 actual: invalid_value,
203 max_allowed: 0b0000_0011,
204 value_type: ValueType::MacsecAn
205 }
206 );
207 }
208 {
210 assert_eq!(
211 MacsecAn::try_from(valid_value).unwrap().value(),
212 valid_value
213 );
214
215 assert_eq!(
216 MacsecAn::try_from(invalid_value).unwrap_err(),
217 ValueTooBigError{
218 actual: invalid_value,
219 max_allowed: 0b0000_0011,
220 value_type: ValueType::MacsecAn
221 }
222 );
223 }
224 }
225 }
226
227 proptest! {
228 #[test]
229 fn new_unchecked(valid_value in 0..=0b0000_0011u8) {
230 assert_eq!(
231 valid_value,
232 unsafe {
233 MacsecAn::new_unchecked(valid_value).value()
234 }
235 );
236 }
237 }
238
239 proptest! {
240 #[test]
241 fn fmt(valid_value in 0..=0b0000_0011u8) {
242 assert_eq!(format!("{}", MacsecAn(valid_value)), format!("{}", valid_value));
243 }
244 }
245
246 proptest! {
247 #[test]
248 fn from(valid_value in 0..=0b0000_0011u8,) {
249 let pcp = MacsecAn::try_new(valid_value).unwrap();
250 let actual: u8 = pcp.into();
251 assert_eq!(actual, valid_value);
252 }
253 }
254}