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