1#[cfg(not(feature = "std"))]
2use alloc::string::String;
3
4use crate::std;
5use std::{fmt, result};
6
7use serde::{Deserialize, Serialize};
8
9pub type Result<T> = result::Result<T, Error>;
10pub type JsonRpcResult<T> = result::Result<T, JsonRpcError>;
11
12#[repr(u16)]
14#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
15pub enum HalResult {
16 Success = 0,
17 Failure = 1,
18 LogicFailure = 2,
19 RuntimeFailure = 3,
20 InvalidArgumentFailure = 4,
21 OutOfRangeFailure = 5,
22 NakResponse = 6,
23 IllegalCall = 7,
24 AsyncInterrupted = 8,
25 InsufficientException = 9,
26 TimeOut = 10,
27 ErrorInvalidArguments = 4105,
28 InvalidHandle = 4112,
29 IncompleteArguments = 4113,
30}
31
32impl From<u16> for HalResult {
33 fn from(res: u16) -> Self {
34 match res {
35 0 => Self::Success,
36 1 => Self::Failure,
37 2 => Self::LogicFailure,
38 3 => Self::RuntimeFailure,
39 4 => Self::InvalidArgumentFailure,
40 5 => Self::OutOfRangeFailure,
41 6 => Self::NakResponse,
42 7 => Self::IllegalCall,
43 8 => Self::AsyncInterrupted,
44 9 => Self::InsufficientException,
45 10 => Self::TimeOut,
46 4105 => Self::ErrorInvalidArguments,
47 4112 => Self::InvalidHandle,
48 4113 => Self::IncompleteArguments,
49 _ => Self::Failure,
50 }
51 }
52}
53
54impl From<HalResult> for &'static str {
55 fn from(res: HalResult) -> Self {
56 match res {
57 HalResult::Success => "success",
58 HalResult::Failure => "failure",
59 HalResult::LogicFailure => "logic failure",
60 HalResult::RuntimeFailure => "runtime failure",
61 HalResult::InvalidArgumentFailure => "invalid argument failure",
62 HalResult::OutOfRangeFailure => "out of range failure",
63 HalResult::NakResponse => "NAK response",
64 HalResult::IllegalCall => "illegal call",
65 HalResult::AsyncInterrupted => "async interrupted",
66 HalResult::InsufficientException => "insufficient exception",
67 HalResult::TimeOut => "time out",
68 HalResult::ErrorInvalidArguments => "error invalid arguments",
69 HalResult::InvalidHandle => "invalid handle",
70 HalResult::IncompleteArguments => "incomplete arguments",
71 }
72 }
73}
74
75impl From<&HalResult> for &'static str {
76 fn from(res: &HalResult) -> &'static str {
77 (*res).into()
78 }
79}
80
81impl fmt::Display for HalResult {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 let s = <&'static str>::from(self);
84 let code = (*self) as u16;
85
86 write!(f, "{s}: {code}")
87 }
88}
89
90#[repr(i16)]
92#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
93pub enum HalError {
94 LicenseKeyAuthFailure = -18,
95 BillPresentInEscrow = -15,
96 BillNotPresentInEscrow = -14,
97 BillReject = -13,
98 PrintImageErr = -12,
99 OpenSerialPortFailure = -11,
100 BufferOverflow = -10,
101 DeviceTimeout = -9,
102 LibraryInternalErr = -8,
103 DeviceAlreadyOpen = -7,
104 DeviceNotReady = -6,
105 Cancelled = -5,
106 InvalidData = -3,
107 DeviceBusy = -2,
108 DeviceFailure = -1,
109 RequestFieldInvalid = 1,
110 InternalErr = 2,
111 InternalValidationErr = 3,
112 ComponentNotImplemented = 4,
113 PreconditionFailed = 5,
114 ApplicationTimeout = 6,
115 InvalidDenomination = 7,
116 ApplicationBusy = 8,
117 DeviceCommErr = 9,
118 FirmwareErr = 10,
119 PhysicalTamper = 11,
120 SystemErr = 12,
121 MethodNotImplemented = 13,
122 DecodingErr = 14,
123}
124
125impl From<HalError> for &'static str {
126 fn from(err: HalError) -> Self {
127 match err {
128 HalError::LicenseKeyAuthFailure => "license key auth failure",
129 HalError::BillPresentInEscrow => "bill present in escrow",
130 HalError::BillNotPresentInEscrow => "bill not present in escrow",
131 HalError::BillReject => "bill reject",
132 HalError::PrintImageErr => "print image err",
133 HalError::OpenSerialPortFailure => "open serial port failure",
134 HalError::BufferOverflow => "buffer overflow",
135 HalError::DeviceTimeout => "device timeout",
136 HalError::LibraryInternalErr => "library internal err",
137 HalError::DeviceAlreadyOpen => "device already open",
138 HalError::DeviceNotReady => "device not ready",
139 HalError::Cancelled => "cancelled",
140 HalError::InvalidData => "invalid data",
141 HalError::DeviceBusy => "device busy",
142 HalError::DeviceFailure => "device failure",
143 HalError::RequestFieldInvalid => "request field invalid",
144 HalError::InternalErr => "internal err",
145 HalError::InternalValidationErr => "internal validation err",
146 HalError::ComponentNotImplemented => "component not implemented",
147 HalError::PreconditionFailed => "precondition failed",
148 HalError::ApplicationTimeout => "application timeout",
149 HalError::InvalidDenomination => "invalid denomination",
150 HalError::ApplicationBusy => "application busy",
151 HalError::DeviceCommErr => "device comm err",
152 HalError::FirmwareErr => "firmware err",
153 HalError::PhysicalTamper => "physical tamper",
154 HalError::SystemErr => "system err",
155 HalError::MethodNotImplemented => "method not implemented",
156 HalError::DecodingErr => "decoding err",
157 }
158 }
159}
160
161impl From<&HalError> for &'static str {
162 fn from(err: &HalError) -> Self {
163 (*err).into()
164 }
165}
166
167impl fmt::Display for HalError {
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 let s: &'static str = self.into();
170 let code = (*self) as i32;
171
172 write!(f, "{s}: {code}")
173 }
174}
175
176#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
177pub enum JsonRpcErrorCode {
178 HalResult(HalResult),
179 HalError(HalError),
180 IoError(String),
181 JsonError(String),
182 SerialError(String),
183 GenericError(i64),
184 Stop,
185}
186
187impl From<HalResult> for JsonRpcErrorCode {
188 fn from(err: HalResult) -> Self {
189 Self::HalResult(err)
190 }
191}
192
193impl From<HalError> for JsonRpcErrorCode {
194 fn from(err: HalError) -> Self {
195 Self::HalError(err)
196 }
197}
198
199#[cfg(feature = "std")]
200impl From<std::io::Error> for JsonRpcErrorCode {
201 fn from(err: std::io::Error) -> Self {
202 Self::IoError(format!("{err}"))
203 }
204}
205
206impl From<serde_json::Error> for JsonRpcErrorCode {
207 fn from(err: serde_json::Error) -> Self {
208 Self::JsonError(format!("{err}"))
209 }
210}
211
212impl From<i64> for JsonRpcErrorCode {
213 fn from(err: i64) -> Self {
214 Self::GenericError(err)
215 }
216}
217
218impl fmt::Display for JsonRpcErrorCode {
219 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220 match self {
221 Self::HalResult(err) => write!(f, "Hal result: {err}"),
222 Self::HalError(err) => write!(f, "Hal error: {err}"),
223 Self::IoError(err) => write!(f, "I/O error: {err}"),
224 Self::JsonError(err) => write!(f, "JSON error: {err}"),
225 Self::SerialError(err) => write!(f, "Serial error: {err}"),
226 Self::GenericError(err) => write!(f, "Generic error: {err}"),
227 Self::Stop => write!(f, "Stop"),
228 }
229 }
230}
231
232#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
234pub struct JsonRpcError {
235 pub(crate) code: JsonRpcErrorCode,
237 pub(crate) message: String,
239}
240
241impl JsonRpcError {
242 pub fn new<C, S>(code: C, message: S) -> Self
244 where
245 C: Into<JsonRpcErrorCode>,
246 S: Into<String>,
247 {
248 Self {
249 code: code.into(),
250 message: message.into(),
251 }
252 }
253
254 pub fn failure<S>(message: S) -> Self
256 where
257 S: Into<String>,
258 {
259 Self::new(-1i64, message)
260 }
261
262 pub fn stop() -> Self {
263 Self::new(JsonRpcErrorCode::Stop, "")
264 }
265
266 pub fn code(&self) -> &JsonRpcErrorCode {
268 &self.code
269 }
270
271 pub fn set_code<C>(&mut self, code: C)
273 where
274 C: Into<JsonRpcErrorCode>,
275 {
276 self.code = code.into();
277 }
278
279 pub fn message(&self) -> &str {
281 &self.message
282 }
283
284 pub fn set_message<S>(&mut self, message: S)
286 where
287 S: Into<String>,
288 {
289 self.message = message.into();
290 }
291}
292
293impl fmt::Display for JsonRpcError {
294 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 write!(f, "code[{}]: {}", self.code, self.message)
296 }
297}
298
299impl From<HalResult> for JsonRpcError {
300 fn from(res: HalResult) -> Self {
301 match res {
302 HalResult::Success => Self {
303 code: res.into(),
304 message: String::new(),
305 },
306 HalResult::InvalidHandle => Self {
307 code: HalError::PreconditionFailed.into(),
308 message: "Device handle is invalid".into(),
309 },
310 HalResult::ErrorInvalidArguments => Self {
311 code: HalError::InternalValidationErr.into(),
312 message: "One of the passed arguments is NULL".into(),
313 },
314 HalResult::IncompleteArguments => Self {
315 code: HalError::InternalValidationErr.into(),
316 message: "One of the passed arguments is incomplete (wrong length)".into(),
317 },
318 hal_result => Self {
319 code: hal_result.into(),
320 message: String::new(),
321 },
322 }
323 }
324}
325
326#[cfg(feature = "std")]
327impl From<JsonRpcError> for std::io::Error {
328 fn from(err: JsonRpcError) -> Self {
329 Self::new(std::io::ErrorKind::Other, format!("{err}"))
330 }
331}
332
333#[cfg(feature = "std")]
334impl From<std::io::Error> for JsonRpcError {
335 fn from(err: std::io::Error) -> Self {
336 Self {
337 code: err.into(),
338 message: String::new(),
339 }
340 }
341}
342
343impl From<serde_json::Error> for JsonRpcError {
344 fn from(err: serde_json::Error) -> Self {
345 Self {
346 code: err.into(),
347 message: String::new(),
348 }
349 }
350}
351
352impl From<std::str::Utf8Error> for JsonRpcError {
353 fn from(err: std::str::Utf8Error) -> Self {
354 Self::failure(format!("{err}"))
355 }
356}
357
358#[repr(C)]
360#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
361pub struct Error {
362 code: ErrorCode,
363 message: String,
364}
365
366impl Error {
367 pub fn failure<S>(message: S) -> Self
369 where
370 S: Into<String>,
371 {
372 Self {
373 code: ErrorCode::Failure,
374 message: message.into(),
375 }
376 }
377
378 pub fn serial<S>(message: S) -> Self
380 where
381 S: Into<String>,
382 {
383 Self {
384 code: ErrorCode::SerialPort,
385 message: message.into(),
386 }
387 }
388
389 pub fn json_rpc<S>(message: S) -> Self
391 where
392 S: Into<String>,
393 {
394 Self {
395 code: ErrorCode::JsonRpc,
396 message: message.into(),
397 }
398 }
399
400 pub fn code(&self) -> ErrorCode {
402 self.code
403 }
404
405 pub fn message(&self) -> &str {
407 self.message.as_str()
408 }
409}
410
411impl fmt::Display for Error {
412 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
413 write!(f, "code: {}, message: {}", self.code, self.message)
414 }
415}
416
417#[cfg(feature = "std")]
418impl From<std::io::Error> for Error {
419 fn from(err: std::io::Error) -> Self {
420 Self {
421 code: ErrorCode::Failure,
422 message: format!("I/O error: {}", err),
423 }
424 }
425}
426
427impl From<std::str::Utf8Error> for Error {
428 fn from(err: std::str::Utf8Error) -> Self {
429 Self {
430 code: ErrorCode::Failure,
431 message: format!("Utf8 error: {}", err),
432 }
433 }
434}
435
436impl From<serialport::Error> for Error {
437 fn from(err: serialport::Error) -> Self {
438 Self {
439 code: ErrorCode::SerialPort,
440 message: format!("Serial port error: {err}"),
441 }
442 }
443}
444
445#[cfg(feature = "std")]
446impl<T> From<std::sync::mpsc::SendError<T>> for Error {
447 fn from(err: std::sync::mpsc::SendError<T>) -> Self {
448 Self::failure(format!("failed to send an item to the queue: {err}"))
449 }
450}
451
452impl From<&Error> for JsonRpcError {
453 fn from(err: &Error) -> Self {
454 Self::new(err.code(), err.message())
455 }
456}
457
458impl From<Error> for JsonRpcError {
459 fn from(err: Error) -> Self {
460 Self::from(&err)
461 }
462}
463
464impl From<JsonRpcError> for Error {
465 fn from(err: JsonRpcError) -> Self {
466 Self::from(&err)
467 }
468}
469
470impl From<&JsonRpcError> for Error {
471 fn from(err: &JsonRpcError) -> Self {
472 Self::json_rpc(format!("code[{}]: {}", err.code(), err.message()))
473 }
474}
475
476#[repr(C)]
478#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
479pub enum ErrorCode {
481 Failure = -1,
483 SerialPort = -2,
485 JsonRpc = -3,
487}
488
489impl From<ErrorCode> for &'static str {
490 fn from(e: ErrorCode) -> Self {
491 match e {
492 ErrorCode::Failure => "failure",
493 ErrorCode::SerialPort => "serial port",
494 ErrorCode::JsonRpc => "JSON-RPC",
495 }
496 }
497}
498
499impl From<&ErrorCode> for &'static str {
500 fn from(e: &ErrorCode) -> Self {
501 (*e).into()
502 }
503}
504
505impl From<ErrorCode> for JsonRpcErrorCode {
506 fn from(e: ErrorCode) -> Self {
507 JsonRpcErrorCode::SerialError(format!("{e}"))
508 }
509}
510
511impl From<&ErrorCode> for JsonRpcErrorCode {
512 fn from(e: &ErrorCode) -> Self {
513 (*e).into()
514 }
515}
516
517impl From<JsonRpcErrorCode> for ErrorCode {
518 fn from(_e: JsonRpcErrorCode) -> Self {
519 Self::JsonRpc
520 }
521}
522
523impl From<&JsonRpcErrorCode> for ErrorCode {
524 fn from(_e: &JsonRpcErrorCode) -> Self {
525 Self::JsonRpc
526 }
527}
528
529impl fmt::Display for ErrorCode {
530 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
531 write!(f, "{}", <&str>::from(self))
532 }
533}