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 fmt::Display for Error {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Error::UnexpectedEof => write!(f, "{}", lang::UNEXPECTED_EOF),
38 Error::Expected(msg) => write!(f, "Expected {}", msg),
39 Error::InvalidChar(c) => write!(f, "{}: {}", lang::INVALID_CHARACTER, c),
40 Error::MaxStrLength(max) => {
41 write!(f, "{}: {}", lang::STRING_LENGTH_EXCEEDS_MAX, max)
42 }
43 Error::Version(msg) => write!(f, "{}: {}", lang::VERSION_ERROR_PREFIX, msg),
44 Error::Message(msg) => write!(f, "{}: {}", lang::MESSAGE_ERROR_PREFIX, msg),
45 Error::Receivers(msg) => {
46 write!(f, "{}: {}", lang::RECEIVERS_ERROR_PREFIX, msg)
47 }
48 Error::Nodes(msg) => write!(f, "{}: {}", lang::NODES_ERROR_PREFIX, msg),
49 Error::Signal(msg) => write!(f, "{}: {}", lang::SIGNAL_ERROR_PREFIX, msg),
50 Error::Decoding(msg) => write!(f, "{}: {}", lang::DECODING_ERROR_PREFIX, msg),
51 Error::Validation(msg) => write!(f, "{}: {}", lang::VALIDATION_ERROR_PREFIX, msg),
52 }
53 }
54}
55
56impl From<core::num::ParseIntError> for Error {
57 fn from(_err: core::num::ParseIntError) -> Self {
58 Error::Expected(lang::PARSE_NUMBER_FAILED)
59 }
60}
61
62#[cfg(feature = "std")]
64impl std::error::Error for Error {
65 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
66 None
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 #![allow(clippy::float_cmp)]
73
74 #[cfg(feature = "std")]
76 mod tests_with_std {
77 use super::super::Error;
78 use crate::error::lang;
79
80 #[test]
81 fn test_from_parse_int_error() {
82 let parse_error = "invalid".parse::<u32>().unwrap_err();
84 let error: Error = parse_error.into();
85
86 match error {
87 Error::Expected(msg) => {
88 assert_eq!(msg, lang::PARSE_NUMBER_FAILED);
89 }
90 _ => panic!("Expected Error::Expected(lang::PARSE_NUMBER_FAILED)"),
91 }
92 }
93
94 #[test]
95 fn test_display_decoding_error() {
96 let error = Error::Decoding("Test error message");
97 let display = error.to_string();
98 assert!(display.starts_with(lang::DECODING_ERROR_PREFIX));
99 assert!(display.contains("Test error message"));
100 }
101
102 #[test]
103 fn test_display_signal_error() {
104 let error = Error::Signal("Test signal error");
105 let display = error.to_string();
106 assert!(display.starts_with(lang::SIGNAL_ERROR_PREFIX));
107 assert!(display.contains("Test signal error"));
108 }
109
110 #[test]
111 fn test_display_formatting() {
112 let error = Error::Decoding(
114 "Duplicate message ID: 256 (messages 'EngineData' and 'BrakeData')",
115 );
116 let display = error.to_string();
117 assert!(display.starts_with(lang::DECODING_ERROR_PREFIX));
118 assert!(display.contains("256"));
119 assert!(display.contains("EngineData"));
120 assert!(display.contains("BrakeData"));
121 }
122
123 #[test]
124 fn test_display_from_parse_int_error() {
125 let int_error = "not_a_number".parse::<u32>().unwrap_err();
126 let error: Error = int_error.into();
127 let display = error.to_string();
128
129 assert!(display.contains(lang::PARSE_NUMBER_FAILED));
130 }
131 }
132
133 #[cfg(feature = "std")]
136 mod tests_std {
137 use super::super::Error;
138 use std::error::Error as StdError;
139
140 #[test]
141 fn test_std_error_trait() {
142 let error = Error::Decoding("Test");
143 let _: &dyn StdError = &error;
145
146 assert!(error.source().is_none());
148 }
149 }
150}