1 use crate::err::LenError; 2 3 /// Error that can occur when reading from a [`crate::io::LimitedReader`] 4 #[derive(Debug)] 5 #[cfg(feature = "std")] 6 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 7 pub enum LimitedReadError { 8 /// IO error was encountered while reading header or 9 /// expected packet contents. 10 Io(std::io::Error), 11 12 /// Error when parsing had to be aborted because a 13 /// length limit specified by an upper layer has been 14 /// exceeded. 15 Len(LenError), 16 } 17 18 #[cfg(feature = "std")] 19 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 20 impl LimitedReadError { 21 /// Returns the `std::io::Error` value if the `LimitedReadError` is `Io`. 22 /// Otherwise `None` is returned. 23 #[inline] io(self) -> Option<std::io::Error>24 pub fn io(self) -> Option<std::io::Error> { 25 use LimitedReadError::*; 26 match self { 27 Io(err) => Some(err), 28 _ => None, 29 } 30 } 31 32 /// Returns the `err::LenError` value if it is of value `Len`. 33 /// Otherwise `None` is returned. 34 #[inline] len(self) -> Option<LenError>35 pub fn len(self) -> Option<LenError> { 36 use LimitedReadError::*; 37 match self { 38 Len(err) => Some(err), 39 _ => None, 40 } 41 } 42 } 43 44 #[cfg(feature = "std")] 45 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 46 impl core::fmt::Display for LimitedReadError { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result47 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 48 use LimitedReadError::*; 49 match self { 50 Io(err) => err.fmt(f), 51 Len(err) => err.fmt(f), 52 } 53 } 54 } 55 56 #[cfg(feature = "std")] 57 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] 58 impl std::error::Error for LimitedReadError { source(&self) -> Option<&(dyn std::error::Error + 'static)>59 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 60 use LimitedReadError::*; 61 match self { 62 Io(err) => Some(err), 63 Len(err) => Some(err), 64 } 65 } 66 } 67 68 #[cfg(all(test, feature = "std"))] 69 mod test { 70 use super::{LimitedReadError::*, *}; 71 use crate::{err::Layer, LenSource}; 72 use alloc::format; 73 74 #[test] debug()75 fn debug() { 76 let err = LenError { 77 required_len: 2, 78 len: 1, 79 len_source: LenSource::Slice, 80 layer: Layer::Icmpv4, 81 layer_start_offset: 3, 82 }; 83 assert_eq!(format!("Len({:?})", err.clone()), format!("{:?}", Len(err))); 84 } 85 86 #[test] fmt()87 fn fmt() { 88 { 89 let err = std::io::Error::new( 90 std::io::ErrorKind::UnexpectedEof, 91 "failed to fill whole buffer", 92 ); 93 assert_eq!(format!("{}", err), format!("{}", Io(err))); 94 } 95 { 96 let err = LenError { 97 required_len: 2, 98 len: 1, 99 len_source: LenSource::Slice, 100 layer: Layer::Icmpv4, 101 layer_start_offset: 3, 102 }; 103 assert_eq!(format!("{}", &err), format!("{}", Len(err.clone()))); 104 } 105 } 106 107 #[test] source()108 fn source() { 109 use std::error::Error; 110 assert!(Io(std::io::Error::new( 111 std::io::ErrorKind::UnexpectedEof, 112 "failed to fill whole buffer", 113 )) 114 .source() 115 .is_some()); 116 { 117 let err = LenError { 118 required_len: 2, 119 len: 1, 120 len_source: LenSource::Slice, 121 layer: Layer::Icmpv4, 122 layer_start_offset: 3, 123 }; 124 assert!(Len(err).source().is_some()); 125 } 126 } 127 128 #[test] io()129 fn io() { 130 assert!(Io(std::io::Error::new( 131 std::io::ErrorKind::UnexpectedEof, 132 "failed to fill whole buffer", 133 )) 134 .io() 135 .is_some()); 136 { 137 let err = LenError { 138 required_len: 2, 139 len: 1, 140 len_source: LenSource::Slice, 141 layer: Layer::Icmpv4, 142 layer_start_offset: 3, 143 }; 144 assert!(Len(err).io().is_none()); 145 } 146 } 147 148 #[test] len()149 fn len() { 150 assert_eq!( 151 None, 152 Io(std::io::Error::new( 153 std::io::ErrorKind::UnexpectedEof, 154 "failed to fill whole buffer", 155 )) 156 .len() 157 ); 158 { 159 let err = LenError { 160 required_len: 2, 161 len: 1, 162 len_source: LenSource::Slice, 163 layer: Layer::Icmpv4, 164 layer_start_offset: 3, 165 }; 166 assert_eq!(Some(err.clone()), Len(err.clone()).len()); 167 } 168 } 169 } 170