1 use super::HeaderError; 2 3 /// Error when decoding an IPv6 header via a `std::io::Read` source. 4 #[cfg(feature = "std")] 5 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 6 #[derive(Debug)] 7 pub enum HeaderReadError { 8 /// IO error was encountered while reading header. 9 Io(std::io::Error), 10 11 /// Error caused by the contents of the header. 12 Content(HeaderError), 13 } 14 15 #[cfg(feature = "std")] 16 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 17 impl HeaderReadError { 18 /// Returns the `std::io::Error` value if the `HeaderReadError` is `Io`. 19 /// Otherwise `None` is returned. 20 #[inline] io_error(self) -> Option<std::io::Error>21 pub fn io_error(self) -> Option<std::io::Error> { 22 use HeaderReadError::*; 23 match self { 24 Io(value) => Some(value), 25 _ => None, 26 } 27 } 28 29 /// Returns the `err::ipv6::HeaderError` value if the `HeaderReadError` is `Content`. 30 /// Otherwise `None` is returned. 31 #[inline] content_error(self) -> Option<HeaderError>32 pub fn content_error(self) -> Option<HeaderError> { 33 use HeaderReadError::*; 34 match self { 35 Content(value) => Some(value), 36 _ => None, 37 } 38 } 39 } 40 41 #[cfg(feature = "std")] 42 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 43 impl core::fmt::Display for HeaderReadError { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result44 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 45 use HeaderReadError::*; 46 match self { 47 Io(err) => write!(f, "IPv6 Header IO Error: {}", err), 48 Content(value) => value.fmt(f), 49 } 50 } 51 } 52 53 #[cfg(feature = "std")] 54 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 55 impl std::error::Error for HeaderReadError { source(&self) -> Option<&(dyn std::error::Error + 'static)>56 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 57 use HeaderReadError::*; 58 match self { 59 Io(err) => Some(err), 60 Content(err) => Some(err), 61 } 62 } 63 } 64 65 #[cfg(all(test, feature = "std"))] 66 mod test { 67 use super::{HeaderReadError::*, *}; 68 use alloc::format; 69 70 #[test] debug()71 fn debug() { 72 let err = HeaderError::UnexpectedVersion { version_number: 6 }; 73 assert_eq!( 74 format!("Content({:?})", err.clone()), 75 format!("{:?}", Content(err)) 76 ); 77 } 78 79 #[test] fmt()80 fn fmt() { 81 { 82 let err = std::io::Error::new( 83 std::io::ErrorKind::UnexpectedEof, 84 "failed to fill whole buffer", 85 ); 86 assert_eq!( 87 format!("IPv6 Header IO Error: {}", err), 88 format!("{}", Io(err)) 89 ); 90 } 91 { 92 let err = HeaderError::UnexpectedVersion { version_number: 6 }; 93 assert_eq!(format!("{}", &err), format!("{}", Content(err.clone()))); 94 } 95 } 96 97 #[test] source()98 fn source() { 99 use std::error::Error; 100 assert!(Io(std::io::Error::new( 101 std::io::ErrorKind::UnexpectedEof, 102 "failed to fill whole buffer", 103 )) 104 .source() 105 .is_some()); 106 assert!( 107 Content(HeaderError::UnexpectedVersion { version_number: 6 }) 108 .source() 109 .is_some() 110 ); 111 } 112 113 #[test] io_error()114 fn io_error() { 115 assert!(Io(std::io::Error::new( 116 std::io::ErrorKind::UnexpectedEof, 117 "failed to fill whole buffer", 118 )) 119 .io_error() 120 .is_some()); 121 assert!( 122 Content(HeaderError::UnexpectedVersion { version_number: 6 }) 123 .io_error() 124 .is_none() 125 ); 126 } 127 128 #[test] content_error()129 fn content_error() { 130 assert_eq!( 131 None, 132 Io(std::io::Error::new( 133 std::io::ErrorKind::UnexpectedEof, 134 "failed to fill whole buffer", 135 )) 136 .content_error() 137 ); 138 { 139 let err = HeaderError::UnexpectedVersion { version_number: 6 }; 140 assert_eq!(Some(err.clone()), Content(err.clone()).content_error()); 141 } 142 } 143 } 144