• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::IpNumber;
2 
3 /// Errors in content of IPv4 header extensions that prevent serialization
4 /// or determining the next header.
5 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
6 pub enum ExtsWalkError {
7     /// Error when a header in [`crate::Ipv4Extensions`] is never referenced even
8     /// though it is present in the [`crate::Ipv4Extensions`].
9     ///
10     /// This can occur when calculating the "next header" value or when
11     /// trying to write [crate::Ipv4Extensions`].
12     ExtNotReferenced {
13         /// IpNumber of the header which was not referenced.
14         missing_ext: IpNumber,
15     },
16 }
17 
18 impl core::fmt::Display for ExtsWalkError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result19     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20         use ExtsWalkError::*;
21         match self {
22             ExtNotReferenced{ missing_ext } => write!(
23                 f,
24                 "IPv4 extensions '{:?}' is defined but is not referenced by the 'protocol' the IPv4 header.",
25                 missing_ext
26             ),
27         }
28     }
29 }
30 
31 #[cfg(feature = "std")]
32 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
33 impl std::error::Error for ExtsWalkError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>34     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
35         use ExtsWalkError::*;
36         match self {
37             ExtNotReferenced { missing_ext: _ } => None,
38         }
39     }
40 }
41 
42 #[cfg(test)]
43 mod tests {
44     use super::ExtsWalkError::*;
45     use crate::*;
46     use alloc::format;
47     use std::{
48         collections::hash_map::DefaultHasher,
49         error::Error,
50         hash::{Hash, Hasher},
51     };
52 
53     #[test]
debug()54     fn debug() {
55         assert_eq!(
56             format!(
57                 "ExtNotReferenced {{ missing_ext: {:?} }}",
58                 IpNumber::AUTHENTICATION_HEADER,
59             ),
60             format!(
61                 "{:?}",
62                 ExtNotReferenced {
63                     missing_ext: IpNumber::AUTHENTICATION_HEADER
64                 }
65             )
66         );
67     }
68 
69     #[test]
clone_eq_hash()70     fn clone_eq_hash() {
71         let err = ExtNotReferenced {
72             missing_ext: IpNumber::AUTHENTICATION_HEADER,
73         };
74         assert_eq!(err, err.clone());
75         let hash_a = {
76             let mut hasher = DefaultHasher::new();
77             err.hash(&mut hasher);
78             hasher.finish()
79         };
80         let hash_b = {
81             let mut hasher = DefaultHasher::new();
82             err.clone().hash(&mut hasher);
83             hasher.finish()
84         };
85         assert_eq!(hash_a, hash_b);
86     }
87 
88     #[test]
fmt()89     fn fmt() {
90         assert_eq!(
91             "IPv4 extensions '51 (AH - Authentication Header)' is defined but is not referenced by the 'protocol' the IPv4 header.",
92             format!("{}", ExtNotReferenced{
93                 missing_ext: IpNumber::AUTHENTICATION_HEADER,
94             })
95         );
96     }
97 
98     #[cfg(feature = "std")]
99     #[test]
source()100     fn source() {
101         assert!(ExtNotReferenced {
102             missing_ext: IpNumber::IPV6_FRAGMENTATION_HEADER
103         }
104         .source()
105         .is_none());
106     }
107 }
108