• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::IpNumber;
2 
3 /// Errors in content of IPv6 header extensions that prevent serialization.
4 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
5 pub enum ExtsWalkError {
6     /// Error when a hop-by-hop header is not referenced as the
7     /// first header after the ipv6 header but as a later extension
8     /// header.
9     HopByHopNotAtStart,
10 
11     /// Error when a header in [`crate::Ipv6Extensions`] is never written
12     /// as it is never referenced by any of the other `next_header`
13     /// fields or the initial ip number.
14     ExtNotReferenced {
15         /// IpNumber of the header which was not referenced.
16         missing_ext: IpNumber,
17     },
18 }
19 
20 impl core::fmt::Display for ExtsWalkError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result21     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22         match self {
23             ExtsWalkError::HopByHopNotAtStart =>
24                 write!(f, "IPv6 extensions hop-by-hop is not located directly after the IPv6 header (required by IPv6)."),
25             ExtsWalkError::ExtNotReferenced{ missing_ext } =>
26                 write!(f, "IPv6 extensions '{:?}' is defined but is not referenced by any of the 'next_header' of the other extension headers or the IPv6 header.", missing_ext),
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         None
36     }
37 }
38 
39 #[cfg(test)]
40 mod tests {
41     use super::ExtsWalkError::*;
42     use crate::*;
43     use alloc::format;
44     use std::{
45         collections::hash_map::DefaultHasher,
46         error::Error,
47         hash::{Hash, Hasher},
48     };
49 
50     #[test]
debug()51     fn debug() {
52         assert_eq!("HopByHopNotAtStart", format!("{:?}", HopByHopNotAtStart));
53     }
54 
55     #[test]
clone_eq_hash()56     fn clone_eq_hash() {
57         let err = HopByHopNotAtStart;
58         assert_eq!(err, err.clone());
59         let hash_a = {
60             let mut hasher = DefaultHasher::new();
61             err.hash(&mut hasher);
62             hasher.finish()
63         };
64         let hash_b = {
65             let mut hasher = DefaultHasher::new();
66             err.clone().hash(&mut hasher);
67             hasher.finish()
68         };
69         assert_eq!(hash_a, hash_b);
70     }
71 
72     #[test]
fmt()73     fn fmt() {
74         assert_eq!(
75             "IPv6 extensions hop-by-hop is not located directly after the IPv6 header (required by IPv6).",
76             format!("{}", HopByHopNotAtStart)
77         );
78         assert_eq!(
79             "IPv6 extensions '44 (IPv6-Frag - Fragment Header for IPv6)' is defined but is not referenced by any of the 'next_header' of the other extension headers or the IPv6 header.",
80             format!("{}", ExtNotReferenced{ missing_ext: IpNumber::IPV6_FRAGMENTATION_HEADER })
81         );
82     }
83 
84     #[cfg(feature = "std")]
85     #[test]
source()86     fn source() {
87         assert!(HopByHopNotAtStart.source().is_none());
88         assert!(ExtNotReferenced {
89             missing_ext: IpNumber::IPV6_FRAGMENTATION_HEADER
90         }
91         .source()
92         .is_none());
93     }
94 }
95