xio_base_datatypes/
error_code.rs

1use std;
2use std::fmt;
3use try_from::TryFrom;
4
5#[repr(u16)]
6#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[cfg_attr(
9    feature = "serde",
10    serde(rename_all = "snake_case", deny_unknown_fields)
11)]
12pub enum ErrorCode {
13    Success = 0x0000,
14    Failure = 0x0001,
15    MessageConstructionError = 0x0002,
16    InvalidOptions = 0x0003,
17    OutOfSequence = 0x0011,
18    PayloadTooBig = 0x0012,
19    UnknownMessage = 0x0020,
20    InvalidLength = 0x0021,
21    NonExistingIndex = 0x0100,
22    InvalidCount = 0x0101,
23    UnsupportedType = 0x0102,
24    UnsupportedValue = 0x0103,
25    TypeValueMismatch = 0x0104,
26    InvalidOperation = 0x0105,
27    ExhaustedResources = 0x0106,
28    InvalidState = 0x0107,
29    InsufficientPermission = 0x0108,
30    ProgrammingMistake = 0x0109,
31}
32
33impl TryFrom<u16> for ErrorCode {
34    type Err = std::io::Error;
35    fn try_from(value: u16) -> std::io::Result<Self> {
36        match value {
37            0x0000 => Ok(ErrorCode::Success),
38            0x0001 => Ok(ErrorCode::Failure),
39            0x0002 => Ok(ErrorCode::MessageConstructionError),
40            0x0003 => Ok(ErrorCode::InvalidOptions),
41            0x0011 => Ok(ErrorCode::OutOfSequence),
42            0x0012 => Ok(ErrorCode::PayloadTooBig),
43            0x0020 => Ok(ErrorCode::UnknownMessage),
44            0x0021 => Ok(ErrorCode::InvalidLength),
45            0x0100 => Ok(ErrorCode::NonExistingIndex),
46            0x0101 => Ok(ErrorCode::InvalidCount),
47            0x0102 => Ok(ErrorCode::UnsupportedType),
48            0x0103 => Ok(ErrorCode::UnsupportedValue),
49            0x0104 => Ok(ErrorCode::TypeValueMismatch),
50            0x0105 => Ok(ErrorCode::InvalidOperation),
51            0x0106 => Ok(ErrorCode::ExhaustedResources),
52            0x0107 => Ok(ErrorCode::InvalidState),
53            0x0108 => Ok(ErrorCode::InsufficientPermission),
54            0x0109 => Ok(ErrorCode::ProgrammingMistake),
55            _ => Err(std::io::Error::new(
56                std::io::ErrorKind::InvalidData,
57                format!("Invalid ErrorCode enum value {}", value),
58            )),
59        }
60    }
61}
62
63impl fmt::Display for ErrorCode {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        write!(f, "{:?}", self)
66    }
67}
68
69impl fmt::LowerHex for ErrorCode {
70    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71        write!(f, "{:x}", *self as u16)
72    }
73}
74
75impl fmt::UpperHex for ErrorCode {
76    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
77        write!(f, "{:X}", *self as u16)
78    }
79}
80
81impl<E> Into<::std::result::Result<(), E>> for ErrorCode
82where
83    E: From<ErrorCode>,
84{
85    fn into(self) -> ::std::result::Result<(), E> {
86        match self {
87            ErrorCode::Success => Ok(()),
88            _ => Err(E::from(self)),
89        }
90    }
91}
92
93impl ErrorCode {
94    pub fn is_success(self) -> bool {
95        self == ErrorCode::Success
96    }
97
98    pub fn is_error(self) -> bool {
99        !self.is_success()
100    }
101
102    pub fn success_or_else<F, O>(self, op: O) -> std::result::Result<(), F>
103    where
104        O: FnOnce(ErrorCode) -> F,
105    {
106        if self.is_error() {
107            Err(op(self))
108        } else {
109            Ok(())
110        }
111    }
112}
113
114pub trait HasErrorCode {
115    fn error_code(&self) -> ErrorCode;
116}
117
118impl<'a, T: HasErrorCode> HasErrorCode for &'a T {
119    fn error_code(&self) -> ErrorCode {
120        (**self).error_code()
121    }
122}