• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::HeaderError;
2 use crate::err::LenError;
3 
4 /// Error when decoding a double VLAN header from a slice.
5 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
6 pub enum HeaderSliceError {
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(HeaderError),
13 }
14 
15 impl HeaderSliceError {
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 HeaderSliceError::*;
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 HeaderSliceError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result28     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
29         use HeaderSliceError::*;
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 HeaderSliceError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>40     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41         use HeaderSliceError::*;
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::{HeaderSliceError::*, *};
52     use crate::{err::Layer, LenSource};
53     use alloc::format;
54     use std::{
55         collections::hash_map::DefaultHasher,
56         error::Error,
57         hash::{Hash, Hasher},
58     };
59 
60     #[test]
add_slice_offset()61     fn add_slice_offset() {
62         assert_eq!(
63             Len(LenError {
64                 required_len: 1,
65                 layer: Layer::Icmpv4,
66                 len: 2,
67                 len_source: LenSource::Slice,
68                 layer_start_offset: 3
69             })
70             .add_slice_offset(200),
71             Len(LenError {
72                 required_len: 1,
73                 layer: Layer::Icmpv4,
74                 len: 2,
75                 len_source: LenSource::Slice,
76                 layer_start_offset: 203
77             })
78         );
79         assert_eq!(
80             Content(HeaderError::NonVlanEtherType {
81                 unexpected_ether_type: 1.into()
82             })
83             .add_slice_offset(200),
84             Content(HeaderError::NonVlanEtherType {
85                 unexpected_ether_type: 1.into()
86             })
87         );
88     }
89 
90     #[test]
debug()91     fn debug() {
92         let err = HeaderError::NonVlanEtherType {
93             unexpected_ether_type: 1.into(),
94         };
95         assert_eq!(
96             format!("Content({:?})", err.clone()),
97             format!("{:?}", Content(err))
98         );
99     }
100 
101     #[test]
clone_eq_hash()102     fn clone_eq_hash() {
103         let err = Content(HeaderError::NonVlanEtherType {
104             unexpected_ether_type: 1.into(),
105         });
106         assert_eq!(err, err.clone());
107         let hash_a = {
108             let mut hasher = DefaultHasher::new();
109             err.hash(&mut hasher);
110             hasher.finish()
111         };
112         let hash_b = {
113             let mut hasher = DefaultHasher::new();
114             err.clone().hash(&mut hasher);
115             hasher.finish()
116         };
117         assert_eq!(hash_a, hash_b);
118     }
119 
120     #[test]
fmt()121     fn fmt() {
122         {
123             let err = LenError {
124                 required_len: 1,
125                 layer: Layer::Icmpv4,
126                 len: 2,
127                 len_source: LenSource::Slice,
128                 layer_start_offset: 3,
129             };
130             assert_eq!(format!("{}", &err), format!("{}", Len(err)));
131         }
132         {
133             let err = HeaderError::NonVlanEtherType {
134                 unexpected_ether_type: 1.into(),
135             };
136             assert_eq!(format!("{}", &err), format!("{}", Content(err.clone())));
137         }
138     }
139 
140     #[cfg(feature = "std")]
141     #[test]
source()142     fn source() {
143         assert!(Len(LenError {
144             required_len: 1,
145             layer: Layer::Icmpv4,
146             len: 2,
147             len_source: LenSource::Slice,
148             layer_start_offset: 3
149         })
150         .source()
151         .is_some());
152         assert!(Content(HeaderError::NonVlanEtherType {
153             unexpected_ether_type: 1.into()
154         })
155         .source()
156         .is_some());
157     }
158 }
159