• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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