1 use crate::err::{ip, LenError}; 2 3 /// Errors that can occur when slicing the IP part of a packet. 4 #[derive(Clone, Debug, Eq, PartialEq, Hash)] 5 pub enum SliceError { 6 /// Length related errors (e.g. not enough data in slice). 7 Len(LenError), 8 9 /// Error when decoding an IP header or IP extension header. 10 IpHeaders(ip::HeadersError), 11 } 12 13 impl core::fmt::Display for SliceError { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result14 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 15 use SliceError::*; 16 match self { 17 Len(err) => err.fmt(f), 18 IpHeaders(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 SliceError { source(&self) -> Option<&(dyn std::error::Error + 'static)>26 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 27 use SliceError::*; 28 match self { 29 Len(err) => Some(err), 30 IpHeaders(err) => Some(err), 31 } 32 } 33 } 34 35 #[cfg(test)] 36 mod tests { 37 use super::{ 38 super::{HeaderError::*, HeadersError::*}, 39 SliceError::*, 40 }; 41 use crate::{ 42 err::{Layer, LenError}, 43 LenSource, 44 }; 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 let err = Ip(UnsupportedIpVersion { version_number: 6 }); 55 assert_eq!( 56 format!("IpHeaders({:?})", err.clone()), 57 format!("{:?}", IpHeaders(err)) 58 ); 59 } 60 61 #[test] clone_eq_hash()62 fn clone_eq_hash() { 63 let err = IpHeaders(Ip(UnsupportedIpVersion { version_number: 6 })); 64 assert_eq!(err, err.clone()); 65 let hash_a = { 66 let mut hasher = DefaultHasher::new(); 67 err.hash(&mut hasher); 68 hasher.finish() 69 }; 70 let hash_b = { 71 let mut hasher = DefaultHasher::new(); 72 err.clone().hash(&mut hasher); 73 hasher.finish() 74 }; 75 assert_eq!(hash_a, hash_b); 76 } 77 78 #[test] fmt()79 fn fmt() { 80 // len 81 { 82 let err = LenError { 83 required_len: 1, 84 layer: Layer::Ipv4Packet, 85 len: 2, 86 len_source: LenSource::Slice, 87 layer_start_offset: 3, 88 }; 89 assert_eq!(format!("{}", &err), format!("{}", Len(err))); 90 } 91 // header 92 { 93 let err = Ip(UnsupportedIpVersion { version_number: 6 }); 94 assert_eq!(format!("{}", &err), format!("{}", IpHeaders(err.clone()))); 95 } 96 } 97 98 #[cfg(feature = "std")] 99 #[test] source()100 fn source() { 101 assert!(Len(LenError { 102 required_len: 1, 103 layer: Layer::Ipv4Packet, 104 len: 2, 105 len_source: LenSource::Slice, 106 layer_start_offset: 3 107 }) 108 .source() 109 .is_some()); 110 assert!(IpHeaders(Ip(UnsupportedIpVersion { version_number: 6 })) 111 .source() 112 .is_some()); 113 } 114 } 115