1#![no_std]
20
21use core::{fmt, num};
22use core::convert::TryFrom;
23
24#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
32pub struct Error(num::NonZeroI32);
33
34impl Error {
35 pub const fn new(errno: i32) -> Option<Error> {
38 match num::NonZeroI32::new(errno) {
39 Some(n) => Some(Self(n)),
40 None => errno_out_of_range(),
41 }
42 }
43
44 #[inline]
50 pub const unsafe fn new_unchecked(errno: i32) -> Error {
51 Error(num::NonZeroI32::new_unchecked(errno))
52 }
53
54 #[inline]
56 pub const fn get(&self) -> i32 {
57 self.0.get()
58 }
59
60 #[inline]
62 pub const fn get_nonzero(&self) -> num::NonZeroI32 {
63 self.0
64 }
65}
66
67#[cold]
68#[inline]
69const fn errno_out_of_range() -> Option<Error> {
70 None
71}
72
73impl From<Error> for i32 {
74 #[inline]
75 fn from(err: Error) -> i32 {
76 err.0.get()
77 }
78}
79
80impl From<Error> for num::NonZeroI32 {
81 #[inline]
82 fn from(err: Error) -> num::NonZeroI32 {
83 err.0
84 }
85}
86
87impl From<Error> for i64 {
88 #[inline]
89 fn from(err: Error) -> i64 {
90 err.0.get().into()
91 }
92}
93
94impl From<Error> for num::NonZeroI64 {
95 #[inline]
96 fn from(err: Error) -> num::NonZeroI64 {
97 err.0.into()
98 }
99}
100
101impl fmt::Binary for Error {
102 #[inline]
103 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
104 self.0.fmt(fmt)
105 }
106}
107
108impl fmt::LowerHex for Error {
109 #[inline]
110 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
111 self.0.fmt(fmt)
112 }
113}
114
115impl fmt::UpperHex for Error {
116 #[inline]
117 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
118 self.0.fmt(fmt)
119 }
120}
121
122impl PartialEq<u64> for Error {
123 #[inline]
124 fn eq(&self, other: &u64) -> bool {
125 u64::try_from(self.0.get()).map_or(false, |x| x == *other)
126 }
127}
128
129impl PartialEq<Error> for u64 {
130 #[inline]
131 fn eq(&self, other: &Error) -> bool {
132 u64::try_from(other.0.get()).map_or(false, |x| x == *self)
133 }
134}
135
136impl PartialEq<usize> for Error {
137 #[inline]
138 fn eq(&self, other: &usize) -> bool {
139 usize::try_from(self.0.get()).map_or(false, |x| x == *other)
140 }
141}
142
143impl PartialEq<Error> for usize {
144 #[inline]
145 fn eq(&self, other: &Error) -> bool {
146 usize::try_from(other.0.get()).map_or(false, |x| x == *self)
147 }
148}
149
150impl PartialEq<isize> for Error {
151 #[inline]
152 fn eq(&self, other: &isize) -> bool {
153 isize::try_from(self.0.get()).map_or(false, |x| x == *other)
154 }
155}
156
157impl PartialEq<Error> for isize {
158 #[inline]
159 fn eq(&self, other: &Error) -> bool {
160 isize::try_from(other.0.get()).map_or(false, |x| x == *self)
161 }
162}
163
164impl PartialEq<num::NonZeroU64> for Error {
165 #[inline]
166 fn eq(&self, other: &num::NonZeroU64) -> bool {
167 u64::try_from(self.0.get()).map_or(false, |x| x == other.get())
168 }
169}
170
171impl PartialEq<Error> for num::NonZeroU64 {
172 #[inline]
173 fn eq(&self, other: &Error) -> bool {
174 u64::try_from(other.0.get()).map_or(false, |x| x == self.get())
175 }
176}
177
178impl PartialEq<num::NonZeroUsize> for Error {
179 #[inline]
180 fn eq(&self, other: &num::NonZeroUsize) -> bool {
181 usize::try_from(self.0.get()).map_or(false, |x| x == other.get())
182 }
183}
184
185impl PartialEq<Error> for num::NonZeroUsize {
186 #[inline]
187 fn eq(&self, other: &Error) -> bool {
188 usize::try_from(other.0.get()).map_or(false, |x| x == self.get())
189 }
190}
191
192impl PartialEq<num::NonZeroIsize> for Error {
193 #[inline]
194 fn eq(&self, other: &num::NonZeroIsize) -> bool {
195 isize::try_from(self.0.get()).map_or(false, |x| x == other.get())
196 }
197}
198
199impl PartialEq<Error> for num::NonZeroIsize {
200 #[inline]
201 fn eq(&self, other: &Error) -> bool {
202 isize::try_from(other.0.get()).map_or(false, |x| x == self.get())
203 }
204}
205
206macro_rules! impl_partial_eq {
207 ($t:ty, $via_t:ty) => {
208 impl PartialEq<$t> for Error {
209 #[inline]
210 fn eq(&self, other: &$t) -> bool {
211 <$via_t>::from(self.0.get()) == <$via_t>::from(*other)
212 }
213 }
214
215 impl PartialEq<Error> for $t {
216 #[inline]
217 fn eq(&self, other: &Error) -> bool {
218 <$via_t>::from(other.0.get()) == <$via_t>::from(*self)
219 }
220 }
221 };
222}
223
224macro_rules! impl_partial_eq_nonzero {
225 ($t:ty, $via_t:ty) => {
226 impl PartialEq<$t> for Error {
227 #[inline]
228 fn eq(&self, other: &$t) -> bool {
229 <$via_t>::from(self.0.get()) == <$via_t>::from(other.get())
230 }
231 }
232
233 impl PartialEq<Error> for $t {
234 #[inline]
235 fn eq(&self, other: &Error) -> bool {
236 <$via_t>::from(other.0.get()) == <$via_t>::from(self.get())
237 }
238 }
239 };
240}
241
242impl_partial_eq!(i16, i32);
243impl_partial_eq!(i32, i32);
244impl_partial_eq!(i64, i64);
245impl_partial_eq!(u16, i32);
246impl_partial_eq!(u32, i64);
247
248impl_partial_eq_nonzero!(num::NonZeroI16, i32);
249impl_partial_eq_nonzero!(num::NonZeroI32, i32);
250impl_partial_eq_nonzero!(num::NonZeroI64, i64);
251impl_partial_eq_nonzero!(num::NonZeroU16, i32);
252impl_partial_eq_nonzero!(num::NonZeroU32, i64);
253
254macro_rules! errno_constants {
255 ( $( $(#[$meta:meta])* $name:ident = $value:literal , )+ ) => {
256 $(
257 $(#[$meta])*
258 pub const $name: $crate::Error = unsafe {
259 $crate::Error::new_unchecked($value)
260 };
261 )*
262
263 #[inline]
264 const fn err_name(err: $crate::Error) -> Option<&'static str> {
265 match err.0.get() {
266 $(
267 $value => Some(stringify!($name)),
268 )*
269 _ => None,
270 }
271 }
272 }
273}
274
275impl fmt::Debug for Error {
276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277 match err_name(*self) {
278 Some(name) => f.write_str(name),
279 _ => f.debug_tuple("Error").field(&self.0.get()).finish(),
280 }
281 }
282}
283
284#[cfg(feature = "posix-traits")]
285const fn from_posix(err: posix_errno::Error) -> Option<Error> {
286 use posix_errno::Error as P;
287 match err {
288 P::E2BIG => Some(E2BIG),
289 P::EACCES => Some(EACCES),
290 P::EADDRINUSE => Some(EADDRINUSE),
291 P::EADDRNOTAVAIL => Some(EADDRNOTAVAIL),
292 P::EAFNOSUPPORT => Some(EAFNOSUPPORT),
293 P::EAGAIN => Some(EAGAIN),
294 P::EALREADY => Some(EALREADY),
295 P::EBADF => Some(EBADF),
296 P::EBADMSG => Some(EBADMSG),
297 P::EBUSY => Some(EBUSY),
298 P::ECANCELED => Some(ECANCELED),
299 P::ECHILD => Some(ECHILD),
300 P::ECONNABORTED => Some(ECONNABORTED),
301 P::ECONNREFUSED => Some(ECONNREFUSED),
302 P::ECONNRESET => Some(ECONNRESET),
303 P::EDEADLK => Some(EDEADLK),
304 P::EDESTADDRREQ => Some(EDESTADDRREQ),
305 P::EDOM => Some(EDOM),
306 P::EDQUOT => Some(EDQUOT),
307 P::EEXIST => Some(EEXIST),
308 P::EFAULT => Some(EFAULT),
309 P::EFBIG => Some(EFBIG),
310 P::EHOSTUNREACH => Some(EHOSTUNREACH),
311 P::EIDRM => Some(EIDRM),
312 P::EILSEQ => Some(EILSEQ),
313 P::EINPROGRESS => Some(EINPROGRESS),
314 P::EINTR => Some(EINTR),
315 P::EINVAL => Some(EINVAL),
316 P::EIO => Some(EIO),
317 P::EISCONN => Some(EISCONN),
318 P::EISDIR => Some(EISDIR),
319 P::ELOOP => Some(ELOOP),
320 P::EMFILE => Some(EMFILE),
321 P::EMLINK => Some(EMLINK),
322 P::EMSGSIZE => Some(EMSGSIZE),
323 P::EMULTIHOP => Some(EMULTIHOP),
324 P::ENAMETOOLONG => Some(ENAMETOOLONG),
325 P::ENETDOWN => Some(ENETDOWN),
326 P::ENETRESET => Some(ENETRESET),
327 P::ENETUNREACH => Some(ENETUNREACH),
328 P::ENFILE => Some(ENFILE),
329 P::ENOBUFS => Some(ENOBUFS),
330 P::ENODATA => None,
331 P::ENODEV => Some(ENODEV),
332 P::ENOENT => Some(ENOENT),
333 P::ENOEXEC => Some(ENOEXEC),
334 P::ENOLCK => Some(ENOLCK),
335 P::ENOLINK => Some(ENOLINK),
336 P::ENOMEM => Some(ENOMEM),
337 P::ENOMSG => Some(ENOMSG),
338 P::ENOPROTOOPT => Some(ENOPROTOOPT),
339 P::ENOSPC => Some(ENOSPC),
340 P::ENOSR => None,
341 P::ENOSTR => None,
342 P::ENOSYS => Some(ENOSYS),
343 P::ENOTCONN => Some(ENOTCONN),
344 P::ENOTDIR => Some(ENOTDIR),
345 P::ENOTEMPTY => Some(ENOTEMPTY),
346 P::ENOTRECOVERABLE => Some(ENOTRECOVERABLE),
347 P::ENOTSOCK => Some(ENOTSOCK),
348 P::ENOTSUP => Some(ENOTSUP),
349 P::ENOTTY => Some(ENOTTY),
350 P::ENXIO => Some(ENXIO),
351 P::EOPNOTSUPP => Some(EOPNOTSUPP),
352 P::EOVERFLOW => Some(EOVERFLOW),
353 P::EOWNERDEAD => Some(EOWNERDEAD),
354 P::EPERM => Some(EPERM),
355 P::EPIPE => Some(EPIPE),
356 P::EPROTO => Some(EPROTO),
357 P::EPROTONOSUPPORT => Some(EPROTONOSUPPORT),
358 P::EPROTOTYPE => Some(EPROTOTYPE),
359 P::ERANGE => Some(ERANGE),
360 P::EROFS => Some(EROFS),
361 P::ESPIPE => Some(ESPIPE),
362 P::ESRCH => Some(ESRCH),
363 P::ESTALE => Some(ESTALE),
364 P::ETIME => None,
365 P::ETIMEDOUT => Some(ETIMEDOUT),
366 P::ETXTBSY => Some(ETXTBSY),
367 P::EWOULDBLOCK => Some(EWOULDBLOCK),
368 P::EXDEV => Some(EXDEV),
369 _ => None,
370 }
371}
372
373#[cfg(any(feature = "posix-traits", doc))]
374impl PartialEq<posix_errno::Error> for Error {
375 #[inline]
376 fn eq(&self, other: &posix_errno::Error) -> bool {
377 from_posix(*other) == Some(*self)
378 }
379}
380
381#[cfg(any(feature = "posix-traits", doc))]
382impl PartialEq<Error> for posix_errno::Error {
383 #[inline]
384 fn eq(&self, other: &Error) -> bool {
385 from_posix(*self) == Some(*other)
386 }
387}
388
389errno_constants! {
390 EPERM = 1,
394 ENOENT = 2,
396 ESRCH = 3,
398 EINTR = 4,
400 EIO = 5,
402 ENXIO = 6,
404 E2BIG = 7,
406 ENOEXEC = 8,
408 EBADF = 9,
410 ECHILD = 10,
412 EDEADLK = 11,
414 ENOMEM = 12,
416 EACCES = 13,
418 EFAULT = 14,
420 ENOTBLK = 15,
422 EBUSY = 16,
424 EEXIST = 17,
426 EXDEV = 18,
428 ENODEV = 19,
430 ENOTDIR = 20,
432 EISDIR = 21,
434 EINVAL = 22,
436 ENFILE = 23,
438 EMFILE = 24,
440 ENOTTY = 25,
442 ETXTBSY = 26,
444 EFBIG = 27,
446 ENOSPC = 28,
448 ESPIPE = 29,
450 EROFS = 30,
452 EMLINK = 31,
454 EPIPE = 32,
456 EDOM = 33,
458 ERANGE = 34,
460 EAGAIN = 35,
462 EINPROGRESS = 36,
464 EALREADY = 37,
466 ENOTSOCK = 38,
468 EDESTADDRREQ = 39,
470 EMSGSIZE = 40,
472 EPROTOTYPE = 41,
474 ENOPROTOOPT = 42,
476 EPROTONOSUPPORT = 43,
478 ESOCKTNOSUPPORT = 44,
480 EOPNOTSUPP = 45,
482 EPFNOSUPPORT = 46,
484 EAFNOSUPPORT = 47,
486 EADDRINUSE = 48,
488 EADDRNOTAVAIL = 49,
490 ENETDOWN = 50,
492 ENETUNREACH = 51,
494 ENETRESET = 52,
496 ECONNABORTED = 53,
498 ECONNRESET = 54,
500 ENOBUFS = 55,
502 EISCONN = 56,
504 ENOTCONN = 57,
506 ESHUTDOWN = 58,
508 ETOOMANYREFS = 59,
510 ETIMEDOUT = 60,
512 ECONNREFUSED = 61,
514 ELOOP = 62,
516 ENAMETOOLONG = 63,
518 EHOSTDOWN = 64,
520 EHOSTUNREACH = 65,
522 ENOTEMPTY = 66,
524 EPROCLIM = 67,
526 EUSERS = 68,
528 EDQUOT = 69,
530 ESTALE = 70,
532 EREMOTE = 71,
534 EBADRPC = 72,
536 ERPCMISMATCH = 73,
538 EPROGUNAVAIL = 74,
540 EPROGMISMATCH = 75,
542 EPROCUNAVAIL = 76,
544 ENOLCK = 77,
546 ENOSYS = 78,
548 EFTYPE = 79,
550 EAUTH = 80,
552 ENEEDAUTH = 81,
554 EIDRM = 82,
556 ENOMSG = 83,
558 EOVERFLOW = 84,
560 ECANCELED = 85,
562 EILSEQ = 86,
564 ENOATTR = 87,
566 EDOOFUS = 88,
568 EBADMSG = 89,
570 EMULTIHOP = 90,
572 ENOLINK = 91,
574 EPROTO = 92,
576 ENOTCAPABLE = 93,
578 ECAPMODE = 94,
580 ENOTRECOVERABLE = 95,
582 EOWNERDEAD = 96,
584 EINTEGRITY = 97,
586}
587
588pub const ENOTSUP: crate::Error = EOPNOTSUPP;
590
591pub const EWOULDBLOCK: crate::Error = EAGAIN;