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