1use core::fmt;
11
12#[derive(Clone, Debug, Eq, PartialEq)]
14pub enum ParseError {
15 BufferTooShort {
17 needed: usize,
19 available: usize,
21 },
22 InvalidField {
24 field: &'static str,
26 value: u32,
28 },
29 InvalidExtensionLength {
31 declared: u16,
33 },
34 ExtensionOverflow,
36}
37
38impl fmt::Display for ParseError {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 ParseError::BufferTooShort { needed, available } => {
42 write!(
43 f,
44 "buffer too short: needed {} bytes, got {}",
45 needed, available
46 )
47 }
48 ParseError::InvalidField { field, value } => {
49 write!(f, "invalid {} value: {}", field, value)
50 }
51 ParseError::InvalidExtensionLength { declared } => {
52 write!(f, "extension field length less than 4: {}", declared)
53 }
54 ParseError::ExtensionOverflow => {
55 write!(f, "extension field value extends beyond packet")
56 }
57 }
58 }
59}
60
61#[cfg(feature = "std")]
62impl From<ParseError> for std::io::Error {
63 fn from(err: ParseError) -> std::io::Error {
64 let kind = match &err {
65 ParseError::BufferTooShort { .. } => std::io::ErrorKind::UnexpectedEof,
66 ParseError::InvalidField { .. } => std::io::ErrorKind::InvalidData,
67 ParseError::InvalidExtensionLength { .. } => std::io::ErrorKind::InvalidData,
68 ParseError::ExtensionOverflow => std::io::ErrorKind::InvalidData,
69 };
70 std::io::Error::new(kind, err)
71 }
72}
73
74#[cfg(feature = "std")]
75impl std::error::Error for ParseError {}
76
77#[cfg(all(test, feature = "std"))]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_display_buffer_too_short() {
83 let err = ParseError::BufferTooShort {
84 needed: 48,
85 available: 10,
86 };
87 assert_eq!(err.to_string(), "buffer too short: needed 48 bytes, got 10");
88 }
89
90 #[test]
91 fn test_display_invalid_field() {
92 let err = ParseError::InvalidField {
93 field: "leap indicator",
94 value: 5,
95 };
96 assert_eq!(err.to_string(), "invalid leap indicator value: 5");
97 }
98
99 #[test]
100 fn test_display_invalid_extension_length() {
101 let err = ParseError::InvalidExtensionLength { declared: 2 };
102 assert_eq!(err.to_string(), "extension field length less than 4: 2");
103 }
104
105 #[test]
106 fn test_display_extension_overflow() {
107 let err = ParseError::ExtensionOverflow;
108 assert_eq!(
109 err.to_string(),
110 "extension field value extends beyond packet"
111 );
112 }
113
114 #[test]
115 fn test_into_io_error() {
116 let parse_err = ParseError::BufferTooShort {
117 needed: 48,
118 available: 0,
119 };
120 let io_err: std::io::Error = parse_err.into();
121 assert_eq!(io_err.kind(), std::io::ErrorKind::UnexpectedEof);
122 }
123
124 #[test]
125 fn test_parse_error_is_std_error() {
126 let err: Box<dyn std::error::Error> = Box::new(ParseError::ExtensionOverflow);
127 assert_eq!(
128 err.to_string(),
129 "extension field value extends beyond packet"
130 );
131 }
132}