1 use super::HeaderError; 2 3 /// Error when decoding an IP authentication 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(self) -> Option<std::io::Error>21 pub fn io(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::ip_auth::HeaderError` value if it is of value `Content`. 30 /// Otherwise `None` is returned. 31 #[inline] content(self) -> Option<HeaderError>32 pub fn content(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, "IP Authentication 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::ZeroPayloadLen; 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!("IP Authentication Header IO Error: {}", err), 88 format!("{}", Io(err)) 89 ); 90 } 91 { 92 let err = HeaderError::ZeroPayloadLen; 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!(Content(HeaderError::ZeroPayloadLen).source().is_some()); 107 } 108 109 #[test] io()110 fn io() { 111 assert!(Io(std::io::Error::new( 112 std::io::ErrorKind::UnexpectedEof, 113 "failed to fill whole buffer", 114 )) 115 .io() 116 .is_some()); 117 assert!(Content(HeaderError::ZeroPayloadLen).io().is_none()); 118 } 119 120 #[test] content()121 fn content() { 122 assert_eq!( 123 None, 124 Io(std::io::Error::new( 125 std::io::ErrorKind::UnexpectedEof, 126 "failed to fill whole buffer", 127 )) 128 .content() 129 ); 130 { 131 let err = HeaderError::ZeroPayloadLen; 132 assert_eq!(Some(err.clone()), Content(err.clone()).content()); 133 } 134 } 135 } 136