1 use crate::*; 2 3 /// Error when decoding IPv6 extension headers. 4 #[derive(Clone, Debug, Eq, PartialEq, Hash)] 5 pub enum HeaderError { 6 /// Error if the ipv6 hop by hop header does not occur directly after the ipv6 header (see rfc8200 chapter 4.1.) 7 HopByHopNotAtStart, 8 9 /// Error in the ip authentication header. 10 IpAuth(err::ip_auth::HeaderError), 11 } 12 13 impl core::fmt::Display for HeaderError { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result14 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 15 use HeaderError::*; 16 match self { 17 HopByHopNotAtStart => write!(f, "IPv6 Extension Header Error: Encountered an IPv6 hop-by-hop header not directly after the IPv6 header. This is not allowed according to RFC 8200."), 18 IpAuth(err) => err.fmt(f), 19 } 20 } 21 } 22 23 #[cfg(feature = "std")] 24 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 25 impl std::error::Error for HeaderError { source(&self) -> Option<&(dyn std::error::Error + 'static)>26 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 27 use HeaderError::*; 28 match self { 29 HopByHopNotAtStart => None, 30 IpAuth(err) => Some(err), 31 } 32 } 33 } 34 35 #[cfg(test)] 36 mod tests { 37 use super::HeaderError::*; 38 use crate::*; 39 use alloc::format; 40 use std::{ 41 collections::hash_map::DefaultHasher, 42 error::Error, 43 hash::{Hash, Hasher}, 44 }; 45 46 #[test] debug()47 fn debug() { 48 assert_eq!("HopByHopNotAtStart", format!("{:?}", HopByHopNotAtStart)); 49 } 50 51 #[test] clone_eq_hash()52 fn clone_eq_hash() { 53 let err = HopByHopNotAtStart; 54 assert_eq!(err, err.clone()); 55 let hash_a = { 56 let mut hasher = DefaultHasher::new(); 57 err.hash(&mut hasher); 58 hasher.finish() 59 }; 60 let hash_b = { 61 let mut hasher = DefaultHasher::new(); 62 err.clone().hash(&mut hasher); 63 hasher.finish() 64 }; 65 assert_eq!(hash_a, hash_b); 66 } 67 68 #[test] fmt()69 fn fmt() { 70 assert_eq!( 71 "IPv6 Extension Header Error: Encountered an IPv6 hop-by-hop header not directly after the IPv6 header. This is not allowed according to RFC 8200.", 72 format!("{}", HopByHopNotAtStart) 73 ); 74 { 75 let err = err::ip_auth::HeaderError::ZeroPayloadLen; 76 assert_eq!(format!("{}", err), format!("{}", IpAuth(err))); 77 } 78 } 79 80 #[cfg(feature = "std")] 81 #[test] source()82 fn source() { 83 use err::ip_auth::HeaderError::ZeroPayloadLen; 84 85 assert!(HopByHopNotAtStart.source().is_none()); 86 assert!(IpAuth(ZeroPayloadLen).source().is_some()); 87 } 88 } 89