bgpkit_parser/models/network/
asn.rs1#[cfg(feature = "parser")]
2use bytes::{BufMut, Bytes, BytesMut};
3use std::cmp::Ordering;
4use std::fmt::{Debug, Display, Formatter};
5use std::hash::{Hash, Hasher};
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum AsnLength {
12 Bits16,
13 Bits32,
14}
15
16impl AsnLength {
17 pub const fn is_four_byte(&self) -> bool {
18 match self {
19 AsnLength::Bits16 => false,
20 AsnLength::Bits32 => true,
21 }
22 }
23}
24
25#[derive(Clone, Copy, Eq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))]
29pub struct Asn {
30 asn: u32,
31 #[cfg_attr(feature = "serde", serde(skip_serializing, default))]
32 four_byte: bool,
33}
34
35impl Ord for Asn {
36 fn cmp(&self, other: &Self) -> Ordering {
37 self.asn.cmp(&other.asn)
38 }
39}
40
41impl Hash for Asn {
42 fn hash<H: Hasher>(&self, state: &mut H) {
43 self.asn.hash(state);
44 }
45}
46
47impl PartialEq for Asn {
48 fn eq(&self, other: &Self) -> bool {
49 self.asn == other.asn
50 }
51}
52
53impl PartialOrd for Asn {
54 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
55 Some(self.cmp(other))
56 }
57}
58
59impl Asn {
60 pub const RESERVED: Self = Asn::new_16bit(0);
61 #[doc(alias("AS_TRANS"))]
62 pub const TRANSITION: Self = Asn::new_16bit(23456);
63
64 #[inline]
66 pub const fn new_16bit(asn: u16) -> Self {
67 Asn {
68 asn: asn as u32,
69 four_byte: false,
70 }
71 }
72
73 #[inline]
75 pub const fn new_32bit(asn: u32) -> Self {
76 Asn {
77 asn,
78 four_byte: true,
79 }
80 }
81
82 pub const fn required_len(&self) -> AsnLength {
84 if self.asn <= u16::MAX as u32 {
85 return AsnLength::Bits16;
86 }
87
88 AsnLength::Bits32
89 }
90
91 #[inline]
95 pub const fn is_private(&self) -> bool {
96 match self.asn {
97 64512..=65534 => true, 4200000000..=4294967294 => true, _ => false,
100 }
101 }
102
103 #[inline]
114 pub const fn is_reserved(&self) -> bool {
115 match self.asn {
116 0 => true, 112 => true, 23456 => true, 64496..=64511 => true, 64512..=65534 => true, 65535 => true, 65536..=65551 => true, 4200000000..=4294967294 => true, 4294967295 => true, _ => false,
126 }
127 }
128
129 #[inline]
133 pub const fn is_reserved_for_documentation(&self) -> bool {
134 match self.asn {
135 64496..=64511 => true, 65536..=65551 => true, _ => false,
138 }
139 }
140
141 #[inline]
143 pub const fn is_four_byte(&self) -> bool {
144 self.four_byte
145 }
146
147 #[inline]
149 pub const fn to_u32(&self) -> u32 {
150 self.asn
151 }
152}
153
154impl Default for Asn {
156 #[inline]
157 fn default() -> Self {
158 Asn::RESERVED
159 }
160}
161
162impl PartialEq<u32> for Asn {
169 #[inline]
170 fn eq(&self, other: &u32) -> bool {
171 self.asn == *other
172 }
173}
174
175impl From<u32> for Asn {
176 #[inline]
177 fn from(v: u32) -> Self {
178 Asn::new_32bit(v)
179 }
180}
181
182impl From<Asn> for u32 {
183 #[inline]
184 fn from(value: Asn) -> Self {
185 value.asn
186 }
187}
188
189impl From<&Asn> for u32 {
190 #[inline]
191 fn from(value: &Asn) -> Self {
192 value.asn
193 }
194}
195
196impl PartialEq<i32> for Asn {
197 #[inline]
198 fn eq(&self, other: &i32) -> bool {
199 self.asn == *other as u32
200 }
201}
202
203impl From<i32> for Asn {
204 #[inline]
205 fn from(v: i32) -> Self {
206 Asn::new_32bit(v as u32)
207 }
208}
209
210impl From<Asn> for i32 {
211 #[inline]
212 fn from(value: Asn) -> Self {
213 value.asn as i32
214 }
215}
216
217impl From<&Asn> for i32 {
218 #[inline]
219 fn from(value: &Asn) -> Self {
220 value.asn as i32
221 }
222}
223
224impl PartialEq<u16> for Asn {
225 #[inline]
226 fn eq(&self, other: &u16) -> bool {
227 self.asn == *other as u32
228 }
229}
230
231impl From<u16> for Asn {
232 #[inline]
233 fn from(v: u16) -> Self {
234 Asn::new_16bit(v)
235 }
236}
237
238impl From<Asn> for u16 {
239 #[inline]
240 fn from(value: Asn) -> Self {
241 value.asn as u16
242 }
243}
244
245impl From<&Asn> for u16 {
246 #[inline]
247 fn from(value: &Asn) -> Self {
248 value.asn as u16
249 }
250}
251
252impl Display for Asn {
253 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
254 write!(f, "{}", self.asn)
255 }
256}
257
258impl Debug for Asn {
259 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
260 write!(f, "{}", self.asn)
261 }
262}
263
264impl FromStr for Asn {
266 type Err = <u32 as FromStr>::Err;
267
268 #[inline]
269 fn from_str(mut s: &str) -> Result<Self, Self::Err> {
270 if let Some(number) = s.strip_prefix("AS") {
271 s = number;
272 }
273
274 Ok(Asn::new_32bit(u32::from_str(s)?))
275 }
276}
277
278#[cfg(feature = "parser")]
279impl Asn {
280 pub fn encode(&self) -> Bytes {
281 let mut bytes = BytesMut::with_capacity(if self.four_byte { 4 } else { 2 });
282 match self.four_byte {
283 true => bytes.put_u32(self.asn),
284 false => bytes.put_u16(self.asn as u16),
285 }
286 bytes.freeze()
287 }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293 #[cfg(feature = "parser")]
294 use crate::parser::ReadUtils;
295 use std::str::FromStr;
296
297 #[cfg(feature = "parser")]
298 #[test]
299 fn test_asn_encode() {
300 let asn = Asn::new_32bit(123);
301 let mut bytes = asn.encode();
302 assert_eq!(123, bytes.read_u32().unwrap());
303 }
304
305 #[test]
306 fn test_asn_is_reserved() {
307 let asn = Asn::new_32bit(0);
308 assert!(asn.is_reserved());
309
310 let asn = Asn::new_32bit(23456);
311 assert!(asn.is_reserved());
312
313 let asn = Asn::new_32bit(64513);
314 assert!(asn.is_reserved());
315
316 let asn = Asn::new_32bit(65535);
317 assert!(asn.is_reserved());
318
319 let asn = Asn::new_32bit(65536);
320 assert!(asn.is_reserved());
321
322 let asn = Asn::new_32bit(4200000000);
323 assert!(asn.is_reserved());
324
325 let asn = Asn::new_32bit(4294967295);
326 assert!(asn.is_reserved());
327
328 let asn = Asn::new_32bit(112);
329 assert!(asn.is_reserved());
330
331 let asn = Asn::new_32bit(400644);
332 assert!(!asn.is_reserved());
333 }
334
335 #[test]
336 fn test_asn_is_reserved_for_documentation() {
337 let asn = Asn::new_32bit(64497);
338 assert!(asn.is_reserved_for_documentation());
339
340 let asn = Asn::new_32bit(65537);
341 assert!(asn.is_reserved_for_documentation());
342
343 let asn = Asn::new_32bit(65535);
344 assert!(!asn.is_reserved_for_documentation());
345 }
346
347 #[test]
348 fn test_asn_is_private() {
349 let asn = Asn::new_32bit(64512);
350 assert!(asn.is_private());
351
352 let asn = Asn::new_32bit(4200000000);
353 assert!(asn.is_private());
354
355 let asn = Asn::new_32bit(4200000001);
356 assert!(asn.is_private());
357
358 let asn = Asn::new_32bit(400644);
359 assert!(!asn.is_private());
360 }
361
362 #[test]
363 fn test_asn_display() {
364 let asn = Asn::from_str("AS12345").unwrap();
365 assert_eq!(12345, asn.to_u32());
366 let asn = Asn::new_32bit(12345);
367 assert_eq!("12345", format!("{asn}"));
368 let asn = Asn::new_32bit(12345);
369 assert_eq!("12345", format!("{asn:?}"));
370 }
371
372 #[test]
373 fn test_default() {
374 assert_eq!(0, Asn::default().asn)
375 }
376
377 #[test]
378 fn test_conversion() {
379 let asn = Asn::from(12345);
381 assert_eq!(12345, asn.to_u32());
382
383 let asn = Asn::from(12345u16);
384 assert_eq!(12345, asn.to_u32());
385
386 let asn = Asn::from(12345i32);
387 assert_eq!(12345, asn.to_u32());
388
389 let asn = Asn::new_32bit(12345);
391 assert_eq!(12345, u32::from(asn));
392 assert_eq!(12345, u32::from(&asn));
393 assert_eq!(12345, i32::from(asn));
394 assert_eq!(12345, i32::from(&asn));
395 assert_eq!(asn, 12345u16);
396 assert_eq!(asn, 12345u32);
397
398 let asn = Asn::new_16bit(12345);
399 assert_eq!(12345, u16::from(asn));
400 assert_eq!(12345, u16::from(&asn));
401 }
402
403 #[test]
404 fn test_is_four_byte() {
405 let asn = Asn::new_32bit(12345);
406 assert!(asn.is_four_byte());
407 let asn = Asn::new_16bit(12345);
408 assert!(!asn.is_four_byte());
409 }
410
411 #[test]
412 fn test_asn_comparison() {
413 let asn1 = Asn::new_32bit(12345);
414 let asn2 = Asn::new_32bit(12345);
415 assert_eq!(asn1, asn2);
416 assert!(asn1 <= asn2);
417 assert!(asn1 >= asn2);
418
419 let asn3 = Asn::new_32bit(12346);
420 assert!(asn1 < asn3);
421 assert!(asn1 <= asn3);
422 }
423
424 #[test]
425 fn test_required_len() {
426 let asn = Asn::new_32bit(65536);
427 assert_eq!(AsnLength::Bits32, asn.required_len());
428 let asn = Asn::new_32bit(65535);
429 assert_eq!(AsnLength::Bits16, asn.required_len());
430 }
431
432 #[test]
433 #[cfg(feature = "serde")]
434 fn test_asn_length_serialization() {
435 let length_16bit = AsnLength::Bits16;
436 let serialized = serde_json::to_string(&length_16bit).unwrap();
437 assert_eq!(serialized, "\"Bits16\"");
438 let deserialized: AsnLength = serde_json::from_str(&serialized).unwrap();
439 assert_eq!(deserialized, length_16bit);
440
441 let length_32bit = AsnLength::Bits32;
442 let serialized = serde_json::to_string(&length_32bit).unwrap();
443 assert_eq!(serialized, "\"Bits32\"");
444 let deserialized: AsnLength = serde_json::from_str(&serialized).unwrap();
445 assert_eq!(deserialized, length_32bit);
446 }
447}