• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::HeaderError;
2 use crate::err::LenError;
3 
4 /// Error when decoding a TCP 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         match self {
42             HeaderSliceError::Len(err) => Some(err),
43             HeaderSliceError::Content(err) => Some(err),
44         }
45     }
46 }
47 
48 #[cfg(test)]
49 mod tests {
50     use super::{HeaderSliceError::*, *};
51     use crate::{err::Layer, LenSource};
52     use alloc::format;
53     use std::{
54         collections::hash_map::DefaultHasher,
55         error::Error,
56         hash::{Hash, Hasher},
57     };
58 
59     #[test]
add_slice_offset()60     fn add_slice_offset() {
61         use HeaderSliceError::*;
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::DataOffsetTooSmall { data_offset: 1 }).add_slice_offset(200),
81             Content(HeaderError::DataOffsetTooSmall { data_offset: 1 })
82         );
83     }
84 
85     #[test]
debug()86     fn debug() {
87         let err = HeaderError::DataOffsetTooSmall { data_offset: 1 };
88         assert_eq!(
89             format!("Content({:?})", err.clone()),
90             format!("{:?}", Content(err))
91         );
92     }
93 
94     #[test]
clone_eq_hash()95     fn clone_eq_hash() {
96         let err = Content(HeaderError::DataOffsetTooSmall { data_offset: 1 });
97         assert_eq!(err, err.clone());
98         let hash_a = {
99             let mut hasher = DefaultHasher::new();
100             err.hash(&mut hasher);
101             hasher.finish()
102         };
103         let hash_b = {
104             let mut hasher = DefaultHasher::new();
105             err.clone().hash(&mut hasher);
106             hasher.finish()
107         };
108         assert_eq!(hash_a, hash_b);
109     }
110 
111     #[test]
fmt()112     fn fmt() {
113         {
114             let err = LenError {
115                 required_len: 1,
116                 layer: Layer::Icmpv4,
117                 len: 2,
118                 len_source: LenSource::Slice,
119                 layer_start_offset: 3,
120             };
121             assert_eq!(format!("{}", &err), format!("{}", Len(err)));
122         }
123         {
124             let err = HeaderError::DataOffsetTooSmall { data_offset: 1 };
125             assert_eq!(format!("{}", &err), format!("{}", Content(err.clone())));
126         }
127     }
128 
129     #[cfg(feature = "std")]
130     #[test]
source()131     fn source() {
132         assert!(Len(LenError {
133             required_len: 1,
134             layer: Layer::Icmpv4,
135             len: 2,
136             len_source: LenSource::Slice,
137             layer_start_offset: 3
138         })
139         .source()
140         .is_some());
141         assert!(Content(HeaderError::DataOffsetTooSmall { data_offset: 1 })
142             .source()
143             .is_some());
144     }
145 }
146