etherparse/transport/
tcp_option_read_error.rs

1/// Errors that can occour while reading the options of a TCP header.
2#[derive(Clone, Debug, Eq, PartialEq)]
3pub enum TcpOptionReadError {
4    /// Returned if an option id was read, but there was not enough memory in the options left to completely read it.
5    UnexpectedEndOfSlice {
6        option_id: u8,
7        expected_len: u8,
8        actual_len: usize,
9    },
10
11    /// Returned if the option as an unexpected size argument (e.g. != 4 for maximum segment size).
12    UnexpectedSize { option_id: u8, size: u8 },
13
14    /// Returned if an unknown tcp header option is encountered.
15    ///
16    /// The first element is the identifier and the slice contains the rest of data left in the options.
17    UnknownId(u8),
18}
19
20impl core::error::Error for TcpOptionReadError {
21    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
22        None
23    }
24}
25
26impl core::fmt::Display for TcpOptionReadError {
27    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28        use TcpOptionReadError::*;
29        match self {
30            UnexpectedEndOfSlice {
31                option_id,
32                expected_len,
33                actual_len,
34            } => {
35                write!(f, "TcpOptionReadError: Not enough memory left in slice to read option of kind {option_id} (expected at least {expected_len} bytes, only {actual_len} bytes available).")
36            }
37            UnexpectedSize { option_id, size } => {
38                write!(f, "TcpOptionReadError: Length value of the option of kind {option_id} had unexpected value {size}.")
39            }
40            UnknownId(id) => {
41                write!(f, "TcpOptionReadError: Unknown tcp option kind value {id}.")
42            }
43        }
44    }
45}
46
47#[cfg(test)]
48mod test {
49    use crate::*;
50    use alloc::format;
51    use proptest::prelude::*;
52
53    #[test]
54    fn debug() {
55        use TcpOptionReadError::*;
56        assert_eq!(
57            "UnexpectedEndOfSlice { option_id: 1, expected_len: 2, actual_len: 3 }",
58            format!(
59                "{:?}",
60                UnexpectedEndOfSlice {
61                    option_id: 1,
62                    expected_len: 2,
63                    actual_len: 3
64                }
65            )
66        );
67    }
68
69    #[test]
70    fn clone_eq() {
71        use TcpOptionReadError::*;
72        let value = UnexpectedEndOfSlice {
73            option_id: 123,
74            expected_len: 5,
75            actual_len: 4,
76        };
77        assert_eq!(value, value.clone());
78    }
79
80    #[cfg(feature = "std")]
81    proptest! {
82        #[test]
83        fn source(
84            arg_u8_0 in any::<u8>(),
85            arg_u8_1 in any::<u8>(),
86            arg_usize in any::<usize>()
87        ) {
88            use core::error::Error;
89            use crate::TcpOptionReadError::*;
90
91            assert!(UnexpectedEndOfSlice{ option_id: arg_u8_0, expected_len: arg_u8_1, actual_len: arg_usize}.source().is_none());
92            assert!(UnexpectedSize{ option_id: arg_u8_0, size: arg_u8_1 }.source().is_none());
93            assert!(UnknownId(arg_u8_0).source().is_none());
94        }
95    }
96
97    proptest! {
98        #[test]
99        fn fmt(
100            arg_u8_0 in any::<u8>(),
101            arg_u8_1 in any::<u8>(),
102            arg_usize in any::<usize>()
103        ) {
104            use crate::TcpOptionReadError::*;
105
106            assert_eq!(
107                &format!("TcpOptionReadError: Not enough memory left in slice to read option of kind {} (expected at least {} bytes, only {} bytes available).", arg_u8_0, arg_u8_1, arg_usize),
108                &format!("{}", UnexpectedEndOfSlice{ option_id: arg_u8_0, expected_len: arg_u8_1, actual_len: arg_usize})
109            );
110            assert_eq!(
111                &format!("TcpOptionReadError: Length value of the option of kind {} had unexpected value {}.", arg_u8_0, arg_u8_1),
112                &format!("{}", UnexpectedSize{ option_id: arg_u8_0, size: arg_u8_1 })
113            );
114            assert_eq!(
115                &format!("TcpOptionReadError: Unknown tcp option kind value {}.", arg_u8_0),
116                &format!("{}", UnknownId(arg_u8_0))
117            );
118        }
119    }
120}