• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::HeadersError;
2 use crate::err::LenError;
3 
4 /// Error when decoding an IP header from a slice.
5 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
6 pub enum HeadersSliceError {
7     /// Error when an length error is encountered (e.g. unexpected
8     /// end of slice).
9     Len(LenError),
10 
11     /// Error caused by the contents of the header.
12     Content(HeadersError),
13 }
14 
15 impl HeadersSliceError {
16     /// Adds an offset value to all slice length related fields.
17     #[inline]
add_slice_offset(self, offset: usize) -> Self18     pub const fn add_slice_offset(self, offset: usize) -> Self {
19         use HeadersSliceError::*;
20         match self {
21             Len(err) => Len(err.add_offset(offset)),
22             Content(err) => Content(err),
23         }
24     }
25 }
26 
27 impl core::fmt::Display for HeadersSliceError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result28     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
29         use HeadersSliceError::*;
30         match self {
31             Len(err) => err.fmt(f),
32             Content(err) => err.fmt(f),
33         }
34     }
35 }
36 
37 #[cfg(feature = "std")]
38 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
39 impl std::error::Error for HeadersSliceError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>40     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41         use HeadersSliceError::*;
42         match self {
43             Len(err) => Some(err),
44             Content(err) => Some(err),
45         }
46     }
47 }
48 
49 #[cfg(test)]
50 mod tests {
51     use super::{
52         super::{HeaderError::*, HeadersError::*},
53         HeadersSliceError::*,
54         *,
55     };
56     use crate::{err::Layer, LenSource};
57     use alloc::format;
58     use std::{
59         collections::hash_map::DefaultHasher,
60         error::Error,
61         hash::{Hash, Hasher},
62     };
63 
64     #[test]
add_slice_offset()65     fn add_slice_offset() {
66         use HeadersSliceError::*;
67         assert_eq!(
68             Len(LenError {
69                 required_len: 1,
70                 layer: Layer::Icmpv4,
71                 len: 2,
72                 len_source: LenSource::Slice,
73                 layer_start_offset: 3
74             })
75             .add_slice_offset(200),
76             Len(LenError {
77                 required_len: 1,
78                 layer: Layer::Icmpv4,
79                 len: 2,
80                 len_source: LenSource::Slice,
81                 layer_start_offset: 203
82             })
83         );
84         assert_eq!(
85             Content(Ip(UnsupportedIpVersion { version_number: 1 })).add_slice_offset(200),
86             Content(Ip(UnsupportedIpVersion { version_number: 1 }))
87         );
88     }
89 
90     #[test]
debug()91     fn debug() {
92         let err = Ip(UnsupportedIpVersion { version_number: 6 });
93         assert_eq!(
94             format!("Content({:?})", err.clone()),
95             format!("{:?}", Content(err))
96         );
97     }
98 
99     #[test]
clone_eq_hash()100     fn clone_eq_hash() {
101         let err = Content(Ip(UnsupportedIpVersion { version_number: 6 }));
102         assert_eq!(err, err.clone());
103         let hash_a = {
104             let mut hasher = DefaultHasher::new();
105             err.hash(&mut hasher);
106             hasher.finish()
107         };
108         let hash_b = {
109             let mut hasher = DefaultHasher::new();
110             err.clone().hash(&mut hasher);
111             hasher.finish()
112         };
113         assert_eq!(hash_a, hash_b);
114     }
115 
116     #[test]
fmt()117     fn fmt() {
118         {
119             let err = LenError {
120                 required_len: 1,
121                 layer: Layer::Icmpv4,
122                 len: 2,
123                 len_source: LenSource::Slice,
124                 layer_start_offset: 3,
125             };
126             assert_eq!(format!("{}", &err), format!("{}", Len(err)));
127         }
128         {
129             let err = Ip(UnsupportedIpVersion { version_number: 6 });
130             assert_eq!(format!("{}", &err), format!("{}", Content(err.clone())));
131         }
132     }
133 
134     #[cfg(feature = "std")]
135     #[test]
source()136     fn source() {
137         assert!(Len(LenError {
138             required_len: 1,
139             layer: Layer::Icmpv4,
140             len: 2,
141             len_source: LenSource::Slice,
142             layer_start_offset: 3
143         })
144         .source()
145         .is_some());
146         assert!(Content(Ip(UnsupportedIpVersion { version_number: 6 }))
147             .source()
148             .is_some());
149     }
150 }
151