1use core::fmt::{self, Display};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum ErrorKind {
10 NotFound,
12 PermissionDenied,
14 ConnectionRefused,
16 ConnectionReset,
18 ConnectionAborted,
20 NotConnected,
22 AddrInUse,
24 AddrNotAvailable,
26 BrokenPipe,
28 AlreadyExists,
30 WouldBlock,
32 InvalidInput,
34 InvalidData,
36 TimedOut,
38 WriteZero,
40 Interrupted,
42 UnexpectedEof,
44 Unsupported,
46 OutOfMemory,
48 Other,
50}
51
52impl ErrorKind {
53 pub const fn kind(&self) -> Self {
55 *self
56 }
57}
58
59impl From<embedded_io::ErrorKind> for ErrorKind {
60 fn from(kind: embedded_io::ErrorKind) -> Self {
61 use embedded_io::ErrorKind as E;
62 match kind {
63 E::NotFound => Self::NotFound,
64 E::PermissionDenied => Self::PermissionDenied,
65 E::ConnectionRefused => Self::ConnectionRefused,
66 E::ConnectionReset => Self::ConnectionReset,
67 E::ConnectionAborted => Self::ConnectionAborted,
68 E::NotConnected => Self::NotConnected,
69 E::AddrInUse => Self::AddrInUse,
70 E::AddrNotAvailable => Self::AddrNotAvailable,
71 E::BrokenPipe => Self::BrokenPipe,
72 E::AlreadyExists => Self::AlreadyExists,
73 E::InvalidInput => Self::InvalidInput,
74 E::InvalidData => Self::InvalidData,
75 E::TimedOut => Self::TimedOut,
76 E::WriteZero => Self::WriteZero,
77 E::Interrupted => Self::Interrupted,
78 E::Unsupported => Self::Unsupported,
79 E::OutOfMemory => Self::OutOfMemory,
80 _ => Self::Other,
81 }
82 }
83}
84
85impl From<ErrorKind> for embedded_io::ErrorKind {
86 fn from(kind: ErrorKind) -> Self {
87 use embedded_io::ErrorKind as E;
88 match kind {
89 ErrorKind::NotFound => E::NotFound,
90 ErrorKind::PermissionDenied => E::PermissionDenied,
91 ErrorKind::ConnectionRefused => E::ConnectionRefused,
92 ErrorKind::ConnectionReset => E::ConnectionReset,
93 ErrorKind::ConnectionAborted => E::ConnectionAborted,
94 ErrorKind::NotConnected => E::NotConnected,
95 ErrorKind::AddrInUse => E::AddrInUse,
96 ErrorKind::AddrNotAvailable => E::AddrNotAvailable,
97 ErrorKind::BrokenPipe => E::BrokenPipe,
98 ErrorKind::AlreadyExists => E::AlreadyExists,
99 ErrorKind::InvalidInput => E::InvalidInput,
100 ErrorKind::InvalidData => E::InvalidData,
101 ErrorKind::TimedOut => E::TimedOut,
102 ErrorKind::WriteZero => E::WriteZero,
103 ErrorKind::Interrupted => E::Interrupted,
104 ErrorKind::Unsupported => E::Unsupported,
105 ErrorKind::OutOfMemory => E::OutOfMemory,
106 ErrorKind::WouldBlock | ErrorKind::UnexpectedEof | ErrorKind::Other => E::Other,
107 }
108 }
109}
110
111impl Display for ErrorKind {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 write!(f, "{self:?}")
114 }
115}
116
117impl core::error::Error for ErrorKind {}
118
119impl embedded_io::Error for ErrorKind {
120 fn kind(&self) -> embedded_io::ErrorKind {
121 (*self).into()
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
127#[non_exhaustive]
128pub enum Error<E = ErrorKind> {
129 Source(E),
131 Context {
133 kind: ErrorKind,
135 message: Option<&'static str>,
137 },
138}
139
140impl<E> Error<E> {
141 pub const fn from_source(source: E) -> Self {
143 Self::Source(source)
144 }
145
146 pub const fn from_kind(kind: ErrorKind) -> Self {
148 Self::Context {
149 kind,
150 message: None,
151 }
152 }
153
154 pub const fn new(kind: ErrorKind, message: &'static str) -> Self {
156 Self::Context {
157 kind,
158 message: Some(message),
159 }
160 }
161
162 pub const fn other(message: &'static str) -> Self {
164 Self::new(ErrorKind::Other, message)
165 }
166
167 pub const fn source_ref(&self) -> Option<&E> {
169 match self {
170 Self::Source(source) => Some(source),
171 Self::Context { .. } => None,
172 }
173 }
174
175 pub fn into_source(self) -> Option<E> {
177 match self {
178 Self::Source(source) => Some(source),
179 Self::Context { .. } => None,
180 }
181 }
182}
183
184impl<E: embedded_io::Error> Error<E> {
185 pub fn kind(&self) -> ErrorKind {
187 match self {
188 Self::Source(source) => source.kind().into(),
189 Self::Context { kind, .. } => *kind,
190 }
191 }
192
193 pub fn erase(self) -> Error<ErrorKind> {
195 match self {
196 Self::Source(source) => Error::Source(source.kind().into()),
197 Self::Context { kind, message } => Error::Context { kind, message },
198 }
199 }
200}
201
202impl<E: embedded_io::Error> embedded_io::Error for Error<E> {
203 fn kind(&self) -> embedded_io::ErrorKind {
204 Error::<E>::kind(self).into()
205 }
206}
207
208impl<E: Display> Display for Error<E> {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 match self {
211 Self::Source(source) => Display::fmt(source, f),
212 Self::Context {
213 kind,
214 message: Some(message),
215 } => {
216 write!(f, "{kind:?}: {message}")
217 }
218 Self::Context {
219 kind,
220 message: None,
221 } => write!(f, "{kind:?}"),
222 }
223 }
224}
225
226impl<E: core::error::Error> core::error::Error for Error<E> {}
227
228#[cfg(feature = "std")]
229impl From<std::io::Error> for Error<std::io::Error> {
230 fn from(error: std::io::Error) -> Self {
231 Self::Source(error)
232 }
233}
234
235#[cfg(feature = "std")]
236impl From<Error<std::io::Error>> for std::io::Error {
237 fn from(error: Error<std::io::Error>) -> Self {
238 match error {
239 Error::Source(source) => source,
240 Error::Context { kind, message } => match message {
241 Some(message) => std::io::Error::new(std::io::ErrorKind::from(kind), message),
242 None => std::io::Error::from(std::io::ErrorKind::from(kind)),
243 },
244 }
245 }
246}
247
248pub type Result<T, E = ErrorKind> = core::result::Result<T, Error<E>>;
250
251#[cfg(feature = "std")]
252impl From<ErrorKind> for std::io::ErrorKind {
253 fn from(kind: ErrorKind) -> Self {
254 let embedded = embedded_io::ErrorKind::from(kind);
255 embedded.into()
256 }
257}