1use crate::std::{self, fmt};
4
5use alloc::{format, string::String};
6
7use crate::{MessageType, ResponseStatus, STX};
8
9pub type Result<T> = core::result::Result<T, Error>;
11
12#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
14pub enum Error {
15 Generic(i64),
16 Aes(String),
17 Crc((u16, u16)),
18 Encryption(ResponseStatus),
19 InvalidBarcodeCharacters(u8),
20 InvalidDataLength((usize, usize)),
21 InvalidInhibitChannels,
22 InvalidLength((usize, usize)),
23 InvalidEvent((ResponseStatus, ResponseStatus)),
24 InvalidMessage(MessageType),
25 InvalidMessageRaw((MessageType, u8)),
26 InvalidStatus((ResponseStatus, ResponseStatus)),
27 InvalidSTX(u8),
28 PollingReinit,
29 QueueTimeout,
30 #[cfg(feature = "std")]
31 Io(String),
32 #[cfg(feature = "std")]
33 SerialPort(String),
34 Utf8(String),
35 Status(ResponseStatus),
36 Timeout(String),
37 #[cfg(feature = "jsonrpc")]
38 JsonRpc(String),
39 Event(String),
40 Enum(String),
41 Firmware(String),
42}
43
44impl fmt::Display for Error {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 Error::Aes(err) => write!(f, "AES error: {err}"),
48 Error::Crc((have, exp)) => {
49 write!(f, "Bad CRC-16, have: 0x{have:04x}, expected: 0x{exp:04x}")
50 }
51 Error::Encryption(err) => write!(f, "Error sending encrypted message: {err}"),
52 Error::Generic(err) => write!(f, "Generic: {err}"),
53 Error::InvalidBarcodeCharacters(num) => {
54 let min = crate::BARCODE_MIN_CHARS;
55 let max = crate::BARCODE_MAX_CHARS;
56
57 write!(
58 f,
59 "Invalid number of barcode characters: {num}, min: {min}, max: {max}"
60 )
61 }
62 Error::InvalidDataLength((have, exp)) => {
63 write!(f, "Invalid data length, have: {have}, expected: {exp}")
64 }
65 Error::InvalidEvent((have, exp)) => {
66 write!(f, "Invalid device event, have: {have}, expected: {exp}")
67 }
68 Error::InvalidInhibitChannels => {
69 write!(f, "Trying to set an invalid number of inhibit channels")
70 }
71 Error::InvalidLength((have, exp)) => {
72 write!(f, "Invalid message length, have: {have}, expected: {exp}")
73 }
74 Error::InvalidMessage(err) => write!(f, "Invalid message type: {err}"),
75 Error::InvalidMessageRaw((msg, raw)) => {
76 write!(f, "Invalid message type: {msg}, raw type: 0x{raw:02x}")
77 }
78 Error::InvalidStatus((have, exp)) => {
79 write!(f, "Invalid response status, have: {have}, expected: {exp}")
80 }
81 Error::InvalidSTX(err) => {
82 write!(f, "Invalid message STX, have: {err}, expected: {STX}")
83 }
84 Error::PollingReinit => {
85 write!(f, "Background polling already initialized")
86 }
87 Error::QueueTimeout => {
88 write!(f, "Failed to retrieve a queued event before timeout")
89 }
90 #[cfg(feature = "std")]
91 Error::Io(err) => write!(f, "I/O error: {err}"),
92 #[cfg(feature = "std")]
93 Error::SerialPort(err) => write!(f, "Serial port communication error: {err:?}"),
94 Error::Status(err) => write!(f, "Response status: {err}"),
95 Error::Timeout(err) => write!(f, "Failed to perform action before timeout: {err}"),
96 Error::Utf8(err) => write!(f, "UTF8 error occurred: {err}"),
97 #[cfg(feature = "jsonrpc")]
98 Error::JsonRpc(err) => write!(f, "Failed processing JSON-RPC message(s): {err}"),
99 Error::Event(err) => write!(f, "Failed processing event message(s): {err}"),
100 Error::Enum(err) => write!(f, "Enum error: {err}"),
101 Error::Firmware(err) => write!(f, "Firmware error: {err}"),
102 }
103 }
104}
105
106#[cfg(feature = "std")]
107impl From<serialport::Error> for Error {
108 fn from(err: serialport::Error) -> Self {
109 Self::SerialPort(format!("{err}"))
110 }
111}
112
113#[cfg(feature = "std")]
114impl From<std::io::Error> for Error {
115 fn from(err: std::io::Error) -> Self {
116 Self::Io(format!("{err}"))
117 }
118}
119
120impl From<()> for Error {
121 fn from(_err: ()) -> Self {
122 Self::Generic(-1)
123 }
124}
125
126#[cfg(feature = "jsonrpc")]
127impl From<serde_json::Error> for Error {
128 fn from(err: serde_json::Error) -> Self {
129 Self::JsonRpc(format!("{err}"))
130 }
131}
132
133#[cfg(feature = "jsonrpc")]
134impl From<smol_jsonrpc::Error> for Error {
135 fn from(err: smol_jsonrpc::Error) -> Self {
136 Self::JsonRpc(format!("{err}"))
137 }
138}
139
140#[cfg(feature = "jsonrpc")]
141impl From<&Error> for smol_jsonrpc::Error {
142 fn from(err: &Error) -> Self {
143 match err {
144 Error::JsonRpc(e) => Self::new()
145 .with_code(smol_jsonrpc::ErrorCode::ParseError)
146 .with_message(e.as_str()),
147 error => Self::new()
148 .with_code(smol_jsonrpc::ErrorCode::InternalError)
149 .with_message(format!("{error}").as_str()),
150 }
151 }
152}
153
154#[cfg(feature = "jsonrpc")]
155impl From<Error> for smol_jsonrpc::Error {
156 fn from(err: Error) -> Self {
157 (&err).into()
158 }
159}
160
161impl From<std::str::Utf8Error> for Error {
162 fn from(err: std::str::Utf8Error) -> Self {
163 Self::Utf8(format!("{err}"))
164 }
165}
166
167#[cfg(feature = "std")]
168impl From<std::time::SystemTimeError> for Error {
169 fn from(err: std::time::SystemTimeError) -> Self {
170 Self::Io(format!("{err}"))
171 }
172}