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