rpcx_protocol/
error.rs

1use std::{convert::From, error, fmt, result, str};
2
3pub type Result<T> = result::Result<T, Error>;
4
5pub struct Error {
6    repr: Repr,
7}
8
9impl fmt::Debug for Error {
10    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11        fmt::Debug::fmt(&self.repr, f)
12    }
13}
14
15enum Repr {
16    Other(String),
17    Simple(ErrorKind),
18    Custom(Box<Custom>),
19}
20
21#[derive(Debug)]
22struct Custom {
23    kind: ErrorKind,
24    error: Box<dyn error::Error + Send + Sync>,
25}
26
27#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
28pub enum ErrorKind {
29    Protocol,
30    IO,
31    Client,
32    Network,
33    Server,
34    Serialization,
35    Other,
36}
37
38impl ErrorKind {
39    pub(crate) fn as_str(self) -> &'static str {
40        match self {
41            ErrorKind::Protocol => "invalid protocol",
42            ErrorKind::IO => "io issue",
43            ErrorKind::Client => "client error",
44            ErrorKind::Network => "network issue",
45            ErrorKind::Server => "server error",
46            ErrorKind::Serialization => "serialization failure",
47            ErrorKind::Other => "other",
48        }
49    }
50}
51
52impl From<&'static str> for Error {
53    #[inline]
54    fn from(s: &'static str) -> Error {
55        Error {
56            repr: Repr::Other(s.to_owned()),
57        }
58    }
59}
60
61impl From<String> for Error {
62    #[inline]
63    fn from(s: String) -> Error {
64        Error {
65            repr: Repr::Other(s),
66        }
67    }
68}
69
70impl From<serde_json::error::Error> for Error {
71    #[inline]
72    fn from(err: serde_json::error::Error) -> Error {
73        Error::new(ErrorKind::IO, err)
74    }
75}
76
77impl From<std::io::Error> for Error {
78    #[inline]
79    fn from(err: std::io::Error) -> Error {
80        Error::new(ErrorKind::IO, err)
81    }
82}
83
84impl From<Box<dyn std::error::Error + Send + Sync>> for Error {
85    #[inline]
86    fn from(err: Box<dyn std::error::Error + Send + Sync>) -> Error {
87        Error::_new(ErrorKind::Other, err)
88    }
89}
90impl From<ErrorKind> for Error {
91    #[inline]
92    fn from(kind: ErrorKind) -> Error {
93        Error {
94            repr: Repr::Simple(kind),
95        }
96    }
97}
98
99impl Error {
100    pub fn new<E>(kind: ErrorKind, error: E) -> Error
101    where
102        E: Into<Box<dyn error::Error + Send + Sync>>,
103    {
104        Self::_new(kind, error.into())
105    }
106
107    fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
108        Error {
109            repr: Repr::Custom(Box::new(Custom { kind, error })),
110        }
111    }
112
113    pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
114        match self.repr {
115            Repr::Other(..) => None,
116            Repr::Simple(..) => None,
117            Repr::Custom(ref c) => Some(&*c.error),
118        }
119    }
120
121    pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
122        match self.repr {
123            Repr::Other(..) => None,
124            Repr::Simple(..) => None,
125            Repr::Custom(ref mut c) => Some(&mut *c.error),
126        }
127    }
128
129    pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
130        match self.repr {
131            Repr::Other(..) => None,
132            Repr::Simple(..) => None,
133            Repr::Custom(c) => Some(c.error),
134        }
135    }
136
137    pub fn kind(&self) -> ErrorKind {
138        match self.repr {
139            Repr::Other(_) => ErrorKind::Other,
140            Repr::Custom(ref c) => c.kind,
141            Repr::Simple(kind) => kind,
142        }
143    }
144}
145
146impl fmt::Debug for Repr {
147    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
148        match &*self {
149            Repr::Other(s) => write!(fmt, "{}", s),
150            Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
151            Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
152        }
153    }
154}
155
156impl fmt::Display for Error {
157    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
158        match &self.repr {
159            Repr::Other(s) => write!(fmt, "{}", s),
160            Repr::Custom(ref c) => c.error.fmt(fmt),
161            Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
162        }
163    }
164}
165
166impl error::Error for Error {
167    fn description(&self) -> &str {
168        match &self.repr {
169            Repr::Other(s) => &s[..],
170            Repr::Simple(..) => self.kind().as_str(),
171            Repr::Custom(ref c) => c.error.description(),
172        }
173    }
174
175    fn cause(&self) -> Option<&dyn error::Error> {
176        match self.repr {
177            Repr::Other(..) => None,
178            Repr::Simple(..) => None,
179            Repr::Custom(ref c) => c.error.source(),
180        }
181    }
182    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
183        match self.repr {
184            Repr::Other(..) => None,
185            Repr::Simple(..) => None,
186            Repr::Custom(ref c) => c.error.source(),
187        }
188    }
189}