1 #[cfg(feature = "std")]
2 use crate::*;
3 
4 /// Error when decoding the IP header part of a message.
5 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
6 pub enum HeaderError {
7     /// Error when the IP header version field is not equal to 4 or 6.
8     UnsupportedIpVersion {
9         /// The unexpected version number in the IP header.
10         version_number: u8,
11     },
12 
13     /// Error when the ipv4 internet header length is smaller then the header itself (5).
14     Ipv4HeaderLengthSmallerThanHeader {
15         /// The internet header length that was too small.
16         ihl: u8,
17     },
18 }
19 
20 impl core::fmt::Display for HeaderError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result21     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22         use HeaderError::*;
23         match self {
24             UnsupportedIpVersion { version_number } => write!(f, "IP Header Error: Encountered '{}' as IP version number in the IP header (only '4' or '6' are supported).", version_number),
25             Ipv4HeaderLengthSmallerThanHeader { ihl } => write!(f, "IPv4 Header Error: The 'internet header length' value '{}' present in the IPv4 header is smaller than the minimum size of an IPv4 header. The minimum allowed value is '5'.", ihl),
26         }
27     }
28 }
29 
30 #[cfg(feature = "std")]
31 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
32 impl std::error::Error for HeaderError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>33     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
34         use HeaderError::*;
35         match self {
36             UnsupportedIpVersion { version_number: _ } => None,
37             Ipv4HeaderLengthSmallerThanHeader { ihl: _ } => None,
38         }
39     }
40 }
41 
42 #[cfg(test)]
43 mod tests {
44     use super::{HeaderError::*, *};
45     use alloc::format;
46     use std::{
47         collections::hash_map::DefaultHasher,
48         error::Error,
49         hash::{Hash, Hasher},
50     };
51 
52     #[test]
debug()53     fn debug() {
54         assert_eq!(
55             "UnsupportedIpVersion { version_number: 6 }",
56             format!("{:?}", UnsupportedIpVersion { version_number: 6 })
57         );
58     }
59 
60     #[test]
clone_eq_hash()61     fn clone_eq_hash() {
62         let err = HeaderError::UnsupportedIpVersion { version_number: 6 };
63         assert_eq!(err, err.clone());
64         let hash_a = {
65             let mut hasher = DefaultHasher::new();
66             err.hash(&mut hasher);
67             hasher.finish()
68         };
69         let hash_b = {
70             let mut hasher = DefaultHasher::new();
71             err.clone().hash(&mut hasher);
72             hasher.finish()
73         };
74         assert_eq!(hash_a, hash_b);
75     }
76 
77     #[test]
fmt()78     fn fmt() {
79         assert_eq!(
80             "IP Header Error: Encountered '1' as IP version number in the IP header (only '4' or '6' are supported).",
81             format!("{}", UnsupportedIpVersion{ version_number: 1 })
82         );
83         assert_eq!(
84             "IPv4 Header Error: The 'internet header length' value '2' present in the IPv4 header is smaller than the minimum size of an IPv4 header. The minimum allowed value is '5'.",
85             format!("{}", Ipv4HeaderLengthSmallerThanHeader{ ihl: 2 })
86         );
87     }
88 
89     #[cfg(feature = "std")]
90     #[test]
source()91     fn source() {
92         let values = [
93             UnsupportedIpVersion { version_number: 0 },
94             Ipv4HeaderLengthSmallerThanHeader { ihl: 0 },
95         ];
96         for v in values {
97             assert!(v.source().is_none());
98         }
99     }
100 }
101