etherparse/err/ipv6/
header_slice_error.rs

1use super::HeaderError;
2use crate::err::LenError;
3
4/// Error when decoding an IPv6 header from a slice.
5#[derive(Clone, Debug, Eq, PartialEq, Hash)]
6pub 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
15impl HeaderSliceError {
16    /// Adds an offset value to all slice length related fields.
17    #[inline]
18    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
27impl core::fmt::Display for HeaderSliceError {
28    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
37impl core::error::Error for HeaderSliceError {
38    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
39        use HeaderSliceError::*;
40        match self {
41            Len(err) => Some(err),
42            Content(err) => Some(err),
43        }
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::{HeaderSliceError::*, *};
50    use crate::{err::Layer, LenSource};
51    use alloc::format;
52    use std::{
53        collections::hash_map::DefaultHasher,
54        error::Error,
55        hash::{Hash, Hasher},
56    };
57
58    #[test]
59    fn add_slice_offset() {
60        use HeaderSliceError::*;
61        assert_eq!(
62            Len(LenError {
63                required_len: 1,
64                layer: Layer::Icmpv4,
65                len: 2,
66                len_source: LenSource::Slice,
67                layer_start_offset: 3
68            })
69            .add_slice_offset(200),
70            Len(LenError {
71                required_len: 1,
72                layer: Layer::Icmpv4,
73                len: 2,
74                len_source: LenSource::Slice,
75                layer_start_offset: 203
76            })
77        );
78        assert_eq!(
79            Content(HeaderError::UnexpectedVersion { version_number: 1 }).add_slice_offset(200),
80            Content(HeaderError::UnexpectedVersion { version_number: 1 })
81        );
82    }
83
84    #[test]
85    fn debug() {
86        let err = HeaderError::UnexpectedVersion { version_number: 6 };
87        assert_eq!(
88            format!("Content({:?})", err.clone()),
89            format!("{:?}", Content(err))
90        );
91    }
92
93    #[test]
94    fn clone_eq_hash() {
95        let err = Content(HeaderError::UnexpectedVersion { version_number: 6 });
96        assert_eq!(err, err.clone());
97        let hash_a = {
98            let mut hasher = DefaultHasher::new();
99            err.hash(&mut hasher);
100            hasher.finish()
101        };
102        let hash_b = {
103            let mut hasher = DefaultHasher::new();
104            err.clone().hash(&mut hasher);
105            hasher.finish()
106        };
107        assert_eq!(hash_a, hash_b);
108    }
109
110    #[test]
111    fn fmt() {
112        {
113            let err = LenError {
114                required_len: 1,
115                layer: Layer::Icmpv4,
116                len: 2,
117                len_source: LenSource::Slice,
118                layer_start_offset: 3,
119            };
120            assert_eq!(format!("{}", &err), format!("{}", Len(err)));
121        }
122        {
123            let err = HeaderError::UnexpectedVersion { version_number: 6 };
124            assert_eq!(format!("{}", &err), format!("{}", Content(err.clone())));
125        }
126    }
127
128    #[cfg(feature = "std")]
129    #[test]
130    fn source() {
131        assert!(Len(LenError {
132            required_len: 1,
133            layer: Layer::Icmpv4,
134            len: 2,
135            len_source: LenSource::Slice,
136            layer_start_offset: 3
137        })
138        .source()
139        .is_some());
140        assert!(
141            Content(HeaderError::UnexpectedVersion { version_number: 6 })
142                .source()
143                .is_some()
144        );
145    }
146}