• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::HeaderError;
2 use crate::err::LenError;
3 
4 /// Error when decoding an IPv4 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(value) => value.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         use HeaderSliceError::*;
63         assert_eq!(
64             Len(LenError {
65                 required_len: 1,
66                 layer: Layer::Icmpv4,
67                 len: 2,
68                 len_source: LenSource::Slice,
69                 layer_start_offset: 3
70             })
71             .add_slice_offset(200),
72             Len(LenError {
73                 required_len: 1,
74                 layer: Layer::Icmpv4,
75                 len: 2,
76                 len_source: LenSource::Slice,
77                 layer_start_offset: 203
78             })
79         );
80         assert_eq!(
81             Content(HeaderError::UnexpectedVersion { version_number: 1 }).add_slice_offset(200),
82             Content(HeaderError::UnexpectedVersion { version_number: 1 })
83         );
84     }
85 
86     #[test]
debug()87     fn debug() {
88         let err = HeaderError::UnexpectedVersion { version_number: 6 };
89         assert_eq!(
90             format!("Content({:?})", err.clone()),
91             format!("{:?}", Content(err))
92         );
93     }
94 
95     #[test]
clone_eq_hash()96     fn clone_eq_hash() {
97         let err = Content(HeaderError::UnexpectedVersion { version_number: 6 });
98         assert_eq!(err, err.clone());
99         let hash_a = {
100             let mut hasher = DefaultHasher::new();
101             err.hash(&mut hasher);
102             hasher.finish()
103         };
104         let hash_b = {
105             let mut hasher = DefaultHasher::new();
106             err.clone().hash(&mut hasher);
107             hasher.finish()
108         };
109         assert_eq!(hash_a, hash_b);
110     }
111 
112     #[test]
fmt()113     fn fmt() {
114         {
115             let err = LenError {
116                 required_len: 1,
117                 layer: Layer::Icmpv4,
118                 len: 2,
119                 len_source: LenSource::Slice,
120                 layer_start_offset: 3,
121             };
122             assert_eq!(format!("{}", &err), format!("{}", Len(err)));
123         }
124         {
125             let err = HeaderError::UnexpectedVersion { version_number: 6 };
126             assert_eq!(format!("{}", &err), format!("{}", Content(err.clone())));
127         }
128     }
129 
130     #[cfg(feature = "std")]
131     #[test]
source()132     fn source() {
133         assert!(Len(LenError {
134             required_len: 1,
135             layer: Layer::Icmpv4,
136             len: 2,
137             len_source: LenSource::Slice,
138             layer_start_offset: 3
139         })
140         .source()
141         .is_some());
142         assert!(
143             Content(HeaderError::UnexpectedVersion { version_number: 6 })
144                 .source()
145                 .is_some()
146         );
147     }
148 }
149