1use core::fmt;
2
3use crate::error::lang;
4
5#[derive(Debug, PartialEq, Clone)]
9pub enum Error {
10 UnexpectedEof,
12 Expected(&'static str),
14 InvalidChar(char),
16 MaxStrLength(usize),
18 Version(&'static str),
20 Message(&'static str),
22 Receivers(&'static str),
24 Nodes(&'static str),
26 Signal(&'static str),
28 Decoding(&'static str),
30 Validation(&'static str),
32}
33
34impl Error {
35 pub const UNEXPECTED_EOF: &'static str = lang::UNEXPECTED_EOF;
37 pub const EXPECTED_WHITESPACE: &'static str = lang::EXPECTED_WHITESPACE;
38 pub const EXPECTED_PATTERN: &'static str = lang::EXPECTED_PATTERN;
39 pub const EXPECTED_KEYWORD: &'static str = lang::EXPECTED_KEYWORD;
40 pub const EXPECTED_NUMBER: &'static str = lang::EXPECTED_NUMBER;
41 pub const EXPECTED_IDENTIFIER: &'static str = lang::EXPECTED_IDENTIFIER;
42 pub const INVALID_UTF8: &'static str = lang::INVALID_UTF8;
43 pub const INVALID_NUMBER_FORMAT: &'static str = lang::INVALID_NUMBER_FORMAT;
44 pub const PARSE_NUMBER_FAILED: &'static str = lang::PARSE_NUMBER_FAILED;
45 pub const INVALID_CHARACTER: &'static str = lang::INVALID_CHARACTER;
46 pub const STRING_LENGTH_EXCEEDS_MAX: &'static str = lang::STRING_LENGTH_EXCEEDS_MAX;
47 pub const MAX_NAME_SIZE_EXCEEDED: &'static str = lang::MAX_NAME_SIZE_EXCEEDED;
48
49 pub const DECODING_ERROR_PREFIX: &'static str = lang::DECODING_ERROR_PREFIX;
51 pub const VALIDATION_ERROR_PREFIX: &'static str = lang::VALIDATION_ERROR_PREFIX;
52 pub const VERSION_ERROR_PREFIX: &'static str = lang::VERSION_ERROR_PREFIX;
53 pub const MESSAGE_ERROR_PREFIX: &'static str = lang::MESSAGE_ERROR_PREFIX;
54 pub const RECEIVERS_ERROR_PREFIX: &'static str = lang::RECEIVERS_ERROR_PREFIX;
55 pub const NODES_ERROR_PREFIX: &'static str = lang::NODES_ERROR_PREFIX;
56 pub const SIGNAL_ERROR_PREFIX: &'static str = lang::SIGNAL_ERROR_PREFIX;
57
58 pub const SIGNAL_PARSE_INVALID_START_BIT: &'static str = lang::SIGNAL_PARSE_INVALID_START_BIT;
60 pub const SIGNAL_PARSE_INVALID_LENGTH: &'static str = lang::SIGNAL_PARSE_INVALID_LENGTH;
61 pub const SIGNAL_PARSE_INVALID_FACTOR: &'static str = lang::SIGNAL_PARSE_INVALID_FACTOR;
62 pub const SIGNAL_PARSE_INVALID_OFFSET: &'static str = lang::SIGNAL_PARSE_INVALID_OFFSET;
63 pub const SIGNAL_PARSE_INVALID_MIN: &'static str = lang::SIGNAL_PARSE_INVALID_MIN;
64 pub const SIGNAL_PARSE_INVALID_MAX: &'static str = lang::SIGNAL_PARSE_INVALID_MAX;
65 pub const SIGNAL_PARSE_UNIT_TOO_LONG: &'static str = lang::SIGNAL_PARSE_UNIT_TOO_LONG;
66 pub const SIGNAL_NAME_EMPTY: &'static str = lang::SIGNAL_NAME_EMPTY;
67 pub const SIGNAL_LENGTH_TOO_SMALL: &'static str = lang::SIGNAL_LENGTH_TOO_SMALL;
68 pub const SIGNAL_LENGTH_TOO_LARGE: &'static str = lang::SIGNAL_LENGTH_TOO_LARGE;
69 #[cfg(feature = "std")]
70 pub const SIGNAL_LENGTH_REQUIRED: &'static str = lang::SIGNAL_LENGTH_REQUIRED;
71 #[cfg(feature = "std")]
72 pub const SIGNAL_START_BIT_REQUIRED: &'static str = lang::SIGNAL_START_BIT_REQUIRED;
73 #[cfg(feature = "std")]
74 pub const SIGNAL_BYTE_ORDER_REQUIRED: &'static str = lang::SIGNAL_BYTE_ORDER_REQUIRED;
75 #[cfg(feature = "std")]
76 pub const SIGNAL_UNSIGNED_REQUIRED: &'static str = lang::SIGNAL_UNSIGNED_REQUIRED;
77 #[cfg(feature = "std")]
78 pub const SIGNAL_FACTOR_REQUIRED: &'static str = lang::SIGNAL_FACTOR_REQUIRED;
79 #[cfg(feature = "std")]
80 pub const SIGNAL_OFFSET_REQUIRED: &'static str = lang::SIGNAL_OFFSET_REQUIRED;
81 #[cfg(feature = "std")]
82 pub const SIGNAL_MIN_REQUIRED: &'static str = lang::SIGNAL_MIN_REQUIRED;
83 #[cfg(feature = "std")]
84 pub const SIGNAL_MAX_REQUIRED: &'static str = lang::SIGNAL_MAX_REQUIRED;
85 pub const SIGNAL_OVERLAP: &'static str = lang::SIGNAL_OVERLAP;
86 pub const SIGNAL_EXTENDS_BEYOND_MESSAGE: &'static str = lang::SIGNAL_EXTENDS_BEYOND_MESSAGE;
87 pub const SIGNAL_EXTENDS_BEYOND_DATA: &'static str = lang::SIGNAL_EXTENDS_BEYOND_DATA;
88 pub const SIGNAL_RECEIVERS_TOO_MANY: &'static str = lang::SIGNAL_RECEIVERS_TOO_MANY;
89
90 pub const NODES_DUPLICATE_NAME: &'static str = lang::NODES_DUPLICATE_NAME;
92 pub const NODES_TOO_MANY: &'static str = lang::NODES_TOO_MANY;
93 pub const DUPLICATE_MESSAGE_ID: &'static str = lang::DUPLICATE_MESSAGE_ID;
94 pub const SENDER_NOT_IN_NODES: &'static str = lang::SENDER_NOT_IN_NODES;
95 pub const INVALID_RANGE: &'static str = lang::INVALID_RANGE;
96 pub const MESSAGE_TOO_MANY_SIGNALS: &'static str = lang::MESSAGE_TOO_MANY_SIGNALS;
97 pub const EXTENDED_MULTIPLEXING_TOO_MANY: &'static str = lang::EXTENDED_MULTIPLEXING_TOO_MANY;
98 pub const MESSAGE_NAME_EMPTY: &'static str = lang::MESSAGE_NAME_EMPTY;
99 pub const MESSAGE_SENDER_EMPTY: &'static str = lang::MESSAGE_SENDER_EMPTY;
100 pub const MESSAGE_DLC_TOO_SMALL: &'static str = lang::MESSAGE_DLC_TOO_SMALL;
101 pub const MESSAGE_DLC_TOO_LARGE: &'static str = lang::MESSAGE_DLC_TOO_LARGE;
102 #[cfg(feature = "std")]
103 pub const MESSAGE_DLC_REQUIRED: &'static str = lang::MESSAGE_DLC_REQUIRED;
104 pub const MESSAGE_ID_OUT_OF_RANGE: &'static str = lang::MESSAGE_ID_OUT_OF_RANGE;
105 #[cfg(feature = "std")]
106 pub const MESSAGE_ID_REQUIRED: &'static str = lang::MESSAGE_ID_REQUIRED;
107 pub const MESSAGE_INVALID_ID: &'static str = lang::MESSAGE_INVALID_ID;
108 pub const MESSAGE_INVALID_DLC: &'static str = lang::MESSAGE_INVALID_DLC;
109 pub const MESSAGE_NOT_FOUND: &'static str = lang::MESSAGE_NOT_FOUND;
110 pub const PAYLOAD_LENGTH_MISMATCH: &'static str = lang::PAYLOAD_LENGTH_MISMATCH;
111 pub const MULTIPLEXER_SWITCH_NEGATIVE: &'static str = lang::MULTIPLEXER_SWITCH_NEGATIVE;
112 #[cfg(feature = "std")]
113 pub const RECEIVERS_DUPLICATE_NAME: &'static str = lang::RECEIVERS_DUPLICATE_NAME;
114 #[cfg(feature = "std")]
115 pub const VALUE_DESCRIPTION_MESSAGE_NOT_FOUND: &'static str =
116 lang::VALUE_DESCRIPTION_MESSAGE_NOT_FOUND;
117 #[cfg(feature = "std")]
118 pub const VALUE_DESCRIPTION_SIGNAL_NOT_FOUND: &'static str =
119 lang::VALUE_DESCRIPTION_SIGNAL_NOT_FOUND;
120 #[cfg(feature = "std")]
121 pub const VALUE_DESCRIPTIONS_TOO_MANY: &'static str = lang::VALUE_DESCRIPTIONS_TOO_MANY;
122}
123
124impl fmt::Display for Error {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 match self {
127 Error::UnexpectedEof => write!(f, "{}", Error::UNEXPECTED_EOF),
128 Error::Expected(msg) => write!(f, "Expected {}", msg),
129 Error::InvalidChar(c) => write!(f, "{}: {}", Error::INVALID_CHARACTER, c),
130 Error::MaxStrLength(max) => {
131 write!(f, "{}: {}", Error::STRING_LENGTH_EXCEEDS_MAX, max)
132 }
133 Error::Version(msg) => write!(f, "{}: {}", Error::VERSION_ERROR_PREFIX, msg),
134 Error::Message(msg) => write!(f, "{}: {}", Error::MESSAGE_ERROR_PREFIX, msg),
135 Error::Receivers(msg) => {
136 write!(f, "{}: {}", Error::RECEIVERS_ERROR_PREFIX, msg)
137 }
138 Error::Nodes(msg) => write!(f, "{}: {}", Error::NODES_ERROR_PREFIX, msg),
139 Error::Signal(msg) => write!(f, "{}: {}", Error::SIGNAL_ERROR_PREFIX, msg),
140 Error::Decoding(msg) => write!(f, "{}: {}", Error::DECODING_ERROR_PREFIX, msg),
141 Error::Validation(msg) => write!(f, "{}: {}", Error::VALIDATION_ERROR_PREFIX, msg),
142 }
143 }
144}
145
146impl From<core::num::ParseIntError> for Error {
147 fn from(_err: core::num::ParseIntError) -> Self {
148 Error::Expected(Error::PARSE_NUMBER_FAILED)
149 }
150}
151
152#[cfg(feature = "std")]
154impl std::error::Error for Error {
155 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
156 None
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 #![allow(clippy::float_cmp)]
163
164 #[cfg(feature = "std")]
166 mod tests_with_std {
167 use crate::Error;
168
169 #[test]
170 fn test_from_parse_int_error() {
171 let parse_error = "invalid".parse::<u32>().unwrap_err();
173 let error: Error = parse_error.into();
174
175 match error {
176 Error::Expected(msg) => {
177 assert_eq!(msg, Error::PARSE_NUMBER_FAILED);
178 }
179 _ => panic!("Expected Error::Expected(Error::PARSE_NUMBER_FAILED)"),
180 }
181 }
182
183 #[test]
184 fn test_display_decoding_error() {
185 let error = Error::Decoding("Test error message");
186 let display = error.to_string();
187 assert!(display.starts_with(Error::DECODING_ERROR_PREFIX));
188 assert!(display.contains("Test error message"));
189 }
190
191 #[test]
192 fn test_display_signal_error() {
193 let error = Error::Signal("Test signal error");
194 let display = error.to_string();
195 assert!(display.starts_with(Error::SIGNAL_ERROR_PREFIX));
196 assert!(display.contains("Test signal error"));
197 }
198
199 #[test]
200 fn test_display_formatting() {
201 let error = Error::Decoding(
203 "Duplicate message ID: 256 (messages 'EngineData' and 'BrakeData')",
204 );
205 let display = error.to_string();
206 assert!(display.starts_with(Error::DECODING_ERROR_PREFIX));
207 assert!(display.contains("256"));
208 assert!(display.contains("EngineData"));
209 assert!(display.contains("BrakeData"));
210 }
211
212 #[test]
213 fn test_display_from_parse_int_error() {
214 let int_error = "not_a_number".parse::<u32>().unwrap_err();
215 let error: Error = int_error.into();
216 let display = error.to_string();
217
218 assert!(display.contains(Error::PARSE_NUMBER_FAILED));
219 }
220 }
221
222 #[cfg(feature = "std")]
225 mod tests_std {
226 use super::super::Error;
227 use std::error::Error as StdError;
228
229 #[test]
230 fn test_std_error_trait() {
231 let error = Error::Decoding("Test");
232 let _: &dyn StdError = &error;
234
235 assert!(error.source().is_none());
237 }
238 }
239}