1pub mod result_ext;
2
3pub use result_ext::Result;
4
5#[macro_export]
21macro_rules! err {
22 (not_found, $e: expr) => {
23 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NotFound, $e))
24 };
25 (permission_denied, $e: expr) => {
26 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::PermissionDenied, $e))
27 };
28 (conn_refused, $e: expr) => {
29 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ConnectionRefused, $e))
30 };
31 (conn_reset, $e: expr) => {
32 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ConnectionReset, $e))
33 };
34 (host_unreachable, $e: expr) => {
35 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::HostUnreachable, $e))
36 };
37 (net_unreachable, $e: expr) => {
38 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NetworkUnreachable, $e))
39 };
40 (conn_aborted, $e: expr) => {
41 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ConnectionAborted, $e))
42 };
43 (not_connected, $e: expr) => {
44 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NotConnected, $e))
45 };
46 (in_use, $e: expr) => {
47 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::AddrInUse, $e))
48 };
49 (addr_not_available, $e: expr) => {
50 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::AddrNotAvailable, $e))
51 };
52 (net_down, $e: expr) => {
53 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NetworkDown, $e))
54 };
55 (broken_pipe, $e: expr) => {
56 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::BrokenPipe, $e))
57 };
58 (already_exists, $e: expr) => {
59 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::AlreadyExists, $e))
60 };
61 (would_block, $e: expr) => {
62 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::WouldBlock, $e))
63 };
64 (not_a_dir, $e: expr) => {
65 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NotADirectory, $e))
66 };
67 (is_a_dir, $e: expr) => {
68 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::IsADirectory, $e))
69 };
70 (dir_not_empty, $e: expr) => {
71 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::DirectoryNotEmpty, $e))
72 };
73 (read_only_fs, $e: expr) => {
74 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ReadOnlyFilesystem, $e))
75 };
76 (fs_loop, $e: expr) => {
77 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::FilesystemLoop, $e))
78 };
79 (stale_net_filehandle, $e: expr) => {
80 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::StaleNetworkFileHandle, $e))
81 };
82 (invalid_input, $e: expr) => {
83 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::InvalidInput, $e))
84 };
85 (invalid_data, $e: expr) => {
86 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::InvalidData, $e))
87 };
88 (timeout, $e: expr) => {
89 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::TimedOut, $e))
90 };
91 (write_zero, $e: expr) => {
92 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::WriteZero, $e))
93 };
94 (storage_full, $e: expr) => {
95 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::StorageFull, $e))
96 };
97 (not_seekable, $e: expr) => {
98 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::NotSeekable, $e))
99 };
100 (fs_quota_exceeded, $e: expr) => {
101 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::FilesystemQuotaExceeded, $e))
102 };
103 (file_too_large, $e: expr) => {
104 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::FileTooLarge, $e))
105 };
106 (resource_busy, $e: expr) => {
107 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ResourceBusy, $e))
108 };
109 (executable_busy, $e: expr) => {
110 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ExecutableFileBusy, $e))
111 };
112 (deadlock, $e: expr) => {
113 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::Deadlock, $e))
114 };
115 (crosses_devices, $e: expr) => {
116 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::CrossesDevices, $e))
117 };
118 (too_many_links, $e: expr) => {
119 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::TooManyLinks, $e))
120 };
121 (filename_too_long, $e: expr) => {
122 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::FilenameTooLong, $e))
123 };
124 (argument_list_too_long, $e: expr) => {
125 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::ArgumentListTooLong, $e))
126 };
127 (interrupted, $e: expr) => {
128 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::Interrupted, $e))
129 };
130 (unsupported, $e: expr) => {
131 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::Unsupported, $e))
132 };
133 (unexpected_eof, $e: expr) => {
134 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::UnexpectedEof, $e))
135 };
136 (out_of_memory, $e: expr) => {
137 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::OutOfMemory, $e))
138 };
139 (other, $e: expr) => {
140 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::Other, $e))
141 };
142 (uncategorized, $e: expr) => {
143 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::Uncategorized, $e))
144 };
145 ($p: ident, $e: expr) => {
146 $crate::Error::new(::std::io::Error::new(::std::io::ErrorKind::$p, $e))
147 };
148
149 (($($t: tt)*)) => {
150 Err($crate::err!($($t)*))
151 };
152 (@$i: ident) => {
153 {
154 |e| $crate::err!($i, e)
155 }
156 };
157 ($e: expr) => {
158 $crate::err!(other, $e)
159 };
160 ($p: ident, $fmt:expr, $($arg:tt)*) => {
161 $crate::err!($p, format!($fmt, $($arg)*))
162 };
163 ($fmt:expr, $($arg:tt)*) => {
164 $crate::err!(format!($fmt, $($arg)*))
165 };
166}
167
168#[macro_export]
169macro_rules! bail {
170 ($($t: tt)*) => {
171 return Err($crate::err!($($t)*));
172 };
173}
174
175use serde::{ser::SerializeTuple, Deserialize, Serialize};
176use serde_repr::{Deserialize_repr, Serialize_repr};
177use std::{
178 fmt::{Debug, Display},
179 io::ErrorKind as StdErrorKind,
180};
181
182#[repr(transparent)]
183pub struct Error(std::io::Error);
185impl Error {
186 #[inline]
187 pub fn new(e: std::io::Error) -> Self {
189 Error(e)
190 }
191}
192
193impl std::ops::Deref for Error {
194 type Target = std::io::Error;
195
196 #[inline]
197 fn deref(&self) -> &Self::Target {
198 &self.0
199 }
200}
201
202impl std::ops::DerefMut for Error {
203 #[inline]
204 fn deref_mut(&mut self) -> &mut Self::Target {
205 &mut self.0
206 }
207}
208
209impl From<std::io::Error> for Error {
210 #[inline]
211 fn from(error: std::io::Error) -> Self {
212 Error(error)
213 }
214}
215
216impl From<Error> for std::io::Error {
217 #[inline]
218 fn from(error: Error) -> Self {
219 error.0
220 }
221}
222
223impl Display for Error {
224 #[inline]
225 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226 <std::io::Error as Display>::fmt(&self.0, f)
227 }
228}
229impl Debug for Error {
230 #[inline]
231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232 <std::io::Error as Debug>::fmt(&self.0, f)
233 }
234}
235
236impl std::error::Error for Error {
237 #[inline]
238 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
239 self.0.source()
240 }
241
242 #[inline]
243 fn description(&self) -> &str {
244 #[allow(deprecated)]
245 self.0.description()
246 }
247
248 #[inline]
249 fn cause(&self) -> Option<&dyn std::error::Error> {
250 #[allow(deprecated)]
251 self.0.cause()
252 }
253}
254
255impl Serialize for Error {
256 #[inline]
257 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
258 where
259 S: serde::Serializer,
260 {
261 let string = self.0.to_string();
262 let mut tuple = serializer.serialize_tuple(2)?;
263 tuple.serialize_element(&string)?;
264 let kind: ErrorKind = self.0.kind().into();
265 tuple.serialize_element(&kind)?;
266 tuple.end()
267 }
268}
269
270impl<'de> Deserialize<'de> for Error {
271 #[inline]
272 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
273 where
274 D: serde::Deserializer<'de>,
275 {
276 let (error, kind) = <(String, ErrorKind)>::deserialize(deserializer)?;
277 Ok(Error(::std::io::Error::new(kind.into(), error)))
278 }
279}
280
281#[derive(Serialize_repr, Deserialize_repr)]
282#[repr(u8)]
283pub enum ErrorKind {
285 NotFound,
287 PermissionDenied,
289 ConnectionRefused,
291 ConnectionReset,
293 HostUnreachable,
295 NetworkUnreachable,
297 ConnectionAborted,
299 NotConnected,
301 AddrInUse,
304 AddrNotAvailable,
307 NetworkDown,
309 BrokenPipe,
311 AlreadyExists,
313 WouldBlock,
316 NotADirectory,
321 IsADirectory,
325 DirectoryNotEmpty,
327 ReadOnlyFilesystem,
329 FilesystemLoop,
337 StaleNetworkFileHandle,
342 InvalidInput,
344 InvalidData,
355 TimedOut,
357 WriteZero,
367 StorageFull,
371 NotSeekable,
376 FilesystemQuotaExceeded,
378 FileTooLarge,
384 ResourceBusy,
386 ExecutableFileBusy,
391 Deadlock,
396 CrossesDevices,
398 TooManyLinks,
402 FilenameTooLong,
407 ArgumentListTooLong,
412 Interrupted,
416 Unsupported,
420 UnexpectedEof,
430 OutOfMemory,
433 Other,
448 Uncategorized,
454}
455
456impl From<ErrorKind> for StdErrorKind {
457 #[inline(always)]
458 fn from(kind: ErrorKind) -> Self {
459 match kind {
460 ErrorKind::NotFound => StdErrorKind::NotFound,
461 ErrorKind::PermissionDenied => StdErrorKind::PermissionDenied,
462 ErrorKind::ConnectionRefused => StdErrorKind::ConnectionRefused,
463 ErrorKind::ConnectionReset => StdErrorKind::ConnectionReset,
464 ErrorKind::ConnectionAborted => StdErrorKind::ConnectionAborted,
465 ErrorKind::NotConnected => StdErrorKind::NotConnected,
466 ErrorKind::AddrInUse => StdErrorKind::AddrInUse,
467 ErrorKind::AddrNotAvailable => StdErrorKind::AddrNotAvailable,
468 ErrorKind::BrokenPipe => StdErrorKind::BrokenPipe,
469 ErrorKind::AlreadyExists => StdErrorKind::AlreadyExists,
470 ErrorKind::WouldBlock => StdErrorKind::WouldBlock,
471 ErrorKind::InvalidInput => StdErrorKind::InvalidInput,
472 ErrorKind::InvalidData => StdErrorKind::InvalidData,
473 ErrorKind::TimedOut => StdErrorKind::TimedOut,
474 ErrorKind::WriteZero => StdErrorKind::WriteZero,
475 ErrorKind::Interrupted => StdErrorKind::Interrupted,
476 ErrorKind::Unsupported => StdErrorKind::Unsupported,
477 ErrorKind::UnexpectedEof => StdErrorKind::UnexpectedEof,
478 ErrorKind::OutOfMemory => StdErrorKind::OutOfMemory,
479 ErrorKind::Other => StdErrorKind::Other,
480 _ => StdErrorKind::Other,
481 }
482 }
483}
484
485impl From<StdErrorKind> for ErrorKind {
486 #[inline(always)]
487 fn from(kind: StdErrorKind) -> Self {
488 match kind {
489 StdErrorKind::NotFound => ErrorKind::NotFound,
490 StdErrorKind::PermissionDenied => ErrorKind::PermissionDenied,
491 StdErrorKind::ConnectionRefused => ErrorKind::ConnectionRefused,
492 StdErrorKind::ConnectionReset => ErrorKind::ConnectionReset,
493 StdErrorKind::ConnectionAborted => ErrorKind::ConnectionAborted,
494 StdErrorKind::NotConnected => ErrorKind::NotConnected,
495 StdErrorKind::AddrInUse => ErrorKind::AddrInUse,
496 StdErrorKind::AddrNotAvailable => ErrorKind::AddrNotAvailable,
497 StdErrorKind::BrokenPipe => ErrorKind::BrokenPipe,
498 StdErrorKind::AlreadyExists => ErrorKind::AlreadyExists,
499 StdErrorKind::WouldBlock => ErrorKind::WouldBlock,
500 StdErrorKind::InvalidInput => ErrorKind::InvalidInput,
501 StdErrorKind::InvalidData => ErrorKind::InvalidData,
502 StdErrorKind::TimedOut => ErrorKind::TimedOut,
503 StdErrorKind::WriteZero => ErrorKind::WriteZero,
504 StdErrorKind::Interrupted => ErrorKind::Interrupted,
505 StdErrorKind::Unsupported => ErrorKind::Unsupported,
506 StdErrorKind::UnexpectedEof => ErrorKind::UnexpectedEof,
507 StdErrorKind::OutOfMemory => ErrorKind::OutOfMemory,
508 StdErrorKind::Other => ErrorKind::Other,
509 _ => ErrorKind::Other,
510 }
511 }
512}