1#![no_std]
24
25use core::{fmt, num};
26
27#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
35pub struct Error(num::NonZeroU16);
36
37impl Error {
38 pub const fn new(errno: u16) -> Option<Error> {
41 if errno > 0xFFF {
42 return errno_out_of_range();
43 }
44 match num::NonZeroU16::new(errno) {
45 Some(n) => Some(Self(n)),
46 None => errno_out_of_range(),
47 }
48 }
49
50 #[inline]
58 pub const unsafe fn new_unchecked(errno: u16) -> Error {
59 Error(num::NonZeroU16::new_unchecked(errno))
60 }
61
62 #[inline]
64 pub const fn get(&self) -> u16 {
65 self.0.get()
66 }
67
68 #[inline]
70 pub const fn get_nonzero(&self) -> num::NonZeroU16 {
71 self.0
72 }
73}
74
75#[cold]
76#[inline]
77const fn errno_out_of_range() -> Option<Error> {
78 None
79}
80
81impl From<Error> for u16 {
82 #[inline]
83 fn from(err: Error) -> u16 {
84 err.0.get()
85 }
86}
87
88impl From<Error> for num::NonZeroU16 {
89 #[inline]
90 fn from(err: Error) -> num::NonZeroU16 {
91 err.0
92 }
93}
94
95impl From<Error> for u32 {
96 #[inline]
97 fn from(err: Error) -> u32 {
98 err.0.get().into()
99 }
100}
101
102impl From<Error> for num::NonZeroU32 {
103 #[inline]
104 fn from(err: Error) -> num::NonZeroU32 {
105 err.0.into()
106 }
107}
108
109impl From<Error> for i32 {
110 #[inline]
111 fn from(err: Error) -> i32 {
112 err.0.get().into()
113 }
114}
115
116impl From<Error> for num::NonZeroI32 {
117 #[inline]
118 fn from(err: Error) -> num::NonZeroI32 {
119 err.0.into()
120 }
121}
122
123impl From<Error> for u64 {
124 #[inline]
125 fn from(err: Error) -> u64 {
126 err.0.get().into()
127 }
128}
129
130impl From<Error> for num::NonZeroU64 {
131 #[inline]
132 fn from(err: Error) -> num::NonZeroU64 {
133 err.0.into()
134 }
135}
136
137impl From<Error> for i64 {
138 #[inline]
139 fn from(err: Error) -> i64 {
140 err.0.get().into()
141 }
142}
143
144impl From<Error> for num::NonZeroI64 {
145 #[inline]
146 fn from(err: Error) -> num::NonZeroI64 {
147 err.0.into()
148 }
149}
150
151impl fmt::Binary for Error {
152 #[inline]
153 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
154 self.0.fmt(fmt)
155 }
156}
157
158impl fmt::LowerHex for Error {
159 #[inline]
160 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
161 self.0.fmt(fmt)
162 }
163}
164
165impl fmt::UpperHex for Error {
166 #[inline]
167 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
168 self.0.fmt(fmt)
169 }
170}
171
172impl PartialEq<i16> for Error {
173 #[inline]
174 fn eq(&self, other: &i16) -> bool {
175 (*other as u16) == self.0.get()
176 }
177}
178
179impl PartialEq<Error> for i16 {
180 #[inline]
181 fn eq(&self, other: &Error) -> bool {
182 (*self as u16) == other.0.get()
183 }
184}
185
186impl PartialEq<isize> for Error {
187 #[inline]
188 fn eq(&self, other: &isize) -> bool {
189 (*other as usize) == usize::from(self.0.get())
190 }
191}
192
193impl PartialEq<Error> for isize {
194 #[inline]
195 fn eq(&self, other: &Error) -> bool {
196 (*self as usize) == usize::from(other.0.get())
197 }
198}
199
200impl PartialEq<num::NonZeroI16> for Error {
201 #[inline]
202 fn eq(&self, other: &num::NonZeroI16) -> bool {
203 (other.get() as u16) == self.0.get()
204 }
205}
206
207impl PartialEq<Error> for num::NonZeroI16 {
208 #[inline]
209 fn eq(&self, other: &Error) -> bool {
210 (self.get() as u16) == other.0.get()
211 }
212}
213
214impl PartialEq<num::NonZeroIsize> for Error {
215 #[inline]
216 fn eq(&self, other: &num::NonZeroIsize) -> bool {
217 (other.get() as usize) == usize::from(self.0.get())
218 }
219}
220
221impl PartialEq<Error> for num::NonZeroIsize {
222 #[inline]
223 fn eq(&self, other: &Error) -> bool {
224 (self.get() as usize) == usize::from(other.0.get())
225 }
226}
227
228macro_rules! impl_partial_eq {
229 ($t:ty) => {
230 impl PartialEq<$t> for Error {
231 #[inline]
232 fn eq(&self, other: &$t) -> bool {
233 <$t>::from(self.0.get()) == *other
234 }
235 }
236
237 impl PartialEq<Error> for $t {
238 #[inline]
239 fn eq(&self, other: &Error) -> bool {
240 <$t>::from(other.0.get()) == *self
241 }
242 }
243 };
244}
245
246macro_rules! impl_partial_eq_nonzero {
247 ($t:ty) => {
248 impl PartialEq<$t> for Error {
249 #[inline]
250 fn eq(&self, other: &$t) -> bool {
251 <$t>::from(self.0) == *other
252 }
253 }
254
255 impl PartialEq<Error> for $t {
256 #[inline]
257 fn eq(&self, other: &Error) -> bool {
258 <$t>::from(other.0) == *self
259 }
260 }
261 };
262}
263
264impl_partial_eq!(i32);
265impl_partial_eq!(i64);
266impl_partial_eq!(u16);
267impl_partial_eq!(u32);
268impl_partial_eq!(u64);
269impl_partial_eq!(usize);
270
271impl_partial_eq_nonzero!(num::NonZeroI32);
272impl_partial_eq_nonzero!(num::NonZeroI64);
273impl_partial_eq_nonzero!(num::NonZeroU16);
274impl_partial_eq_nonzero!(num::NonZeroU32);
275impl_partial_eq_nonzero!(num::NonZeroU64);
276impl_partial_eq_nonzero!(num::NonZeroUsize);
277
278macro_rules! errno_constants {
279 ( $( $(#[$meta:meta])* $name:ident = $value:literal , )+ ) => {
280 use core::fmt;
281
282 $(
283 $(#[$meta])*
284 pub const $name: $crate::Error = unsafe {
285 $crate::Error::new_unchecked($value)
286 };
287 )*
288
289 #[inline]
290 pub(crate) const fn err_name(err: $crate::Error) -> Option<&'static str> {
291 match err.0.get() {
292 $(
293 $value => Some(stringify!($name)),
294 )*
295 _ => None,
296 }
297 }
298 }
299}
300
301#[path = "linux-errno_generic.rs"]
302mod arch_generic;
303
304#[path = "linux-errno_alpha.rs"]
305mod arch_alpha;
306
307#[path = "linux-errno_mips.rs"]
308mod arch_mips;
309
310#[path = "linux-errno_parisc.rs"]
311mod arch_parisc;
312
313#[path = "linux-errno_sparc.rs"]
314mod arch_sparc;
315
316pub mod arch {
318 #[cfg(any(target_arch = "alpha", doc))]
320 pub mod alpha {
321 pub use crate::arch_alpha::*;
322 }
323
324 #[cfg(any(
326 target_arch = "arm",
327 target_arch = "aarch64",
328 doc,
329 ))]
330 pub mod arm {
331 pub use crate::arch_generic::*;
332 }
333
334 #[cfg(any(target_arch = "m68k", doc))]
336 pub mod m68k {
337 pub use crate::arch_generic::*;
338 }
339
340 #[cfg(any(target_arch = "loongarch64", doc))]
342 pub mod loongarch64 {
343 pub use crate::arch_generic::*;
344 }
345
346 #[cfg(any(
348 target_arch = "mips",
349 target_arch = "mips64",
350 doc,
351 ))]
352 pub mod mips {
353 pub use crate::arch_mips::*;
354 }
355
356 #[cfg(any(
358 target_arch = "powerpc",
359 target_arch = "powerpc64",
360 doc,
361 ))]
362 pub mod powerpc {
363 pub use crate::arch_generic::*;
364
365 pub const EDEADLOCK: crate::Error = unsafe {
367 crate::Error::new_unchecked(58)
368 };
369
370 #[inline]
371 pub(crate) const fn err_name(err: crate::Error) -> Option<&'static str> {
372 if err.0.get() == EDEADLOCK.0.get() {
373 return Some(stringify!("EDEADLOCK"));
374 }
375 crate::arch_generic::err_name(err)
376 }
377 }
378
379 #[cfg(any(target_arch = "parisc", doc))]
381 pub mod parisc {
382 pub use crate::arch_parisc::*;
383 }
384
385 #[cfg(any(
387 target_arch = "riscv32",
388 target_arch = "riscv64",
389 doc,
390 ))]
391 pub mod riscv32 {
392 pub use crate::arch_generic::*;
393 }
394
395 #[cfg(any(target_arch = "s390x", doc))]
397 pub mod s390x {
398 pub use crate::arch_generic::*;
399 }
400
401 #[cfg(any(
403 target_arch = "sparc",
404 target_arch = "sparc64",
405 doc,
406 ))]
407 pub mod sparc {
408 pub use crate::arch_sparc::*;
409 }
410
411 #[cfg(any(
413 target_arch = "x86",
414 target_arch = "x86_64",
415 doc,
416 ))]
417 pub mod x86 {
418 pub use crate::arch_generic::*;
419 }
420}
421
422#[cfg(target_arch = "alpha")]
423use crate::arch::alpha as target;
424
425#[cfg(any(
426 target_arch = "arm",
427 target_arch = "aarch64",
428))]
429use crate::arch::arm as target;
430
431#[cfg(target_arch = "loongarch64")]
432use crate::arch::loongarch64 as target;
433
434#[cfg(any(
435 target_arch = "mips",
436 target_arch = "mips64",
437))]
438use crate::arch::mips as target;
439
440#[cfg(any(
441 target_arch = "powerpc",
442 target_arch = "powerpc64",
443))]
444use crate::arch::powerpc as target;
445
446#[cfg(target_arch = "parisc")]
447use crate::arch::parisc as target;
448
449#[cfg(any(
450 target_arch = "riscv32",
451 target_arch = "riscv64",
452))]
453use crate::arch::riscv32 as target;
454
455#[cfg(target_arch = "s390x")]
456use crate::arch::s390x as target;
457
458#[cfg(any(
459 target_arch = "sparc",
460 target_arch = "sparc64",
461))]
462use crate::arch::sparc as target;
463
464#[cfg(any(
465 target_arch = "x86",
466 target_arch = "x86_64",
467))]
468use crate::arch::x86 as target;
469
470#[doc(inline)]
471pub use crate::target::*;
472
473impl fmt::Debug for Error {
474 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
475 match crate::target::err_name(*self) {
476 Some(name) => f.write_str(name),
477 _ => f.debug_tuple("Error").field(&self.0.get()).finish(),
478 }
479 }
480}
481
482#[cfg(feature = "posix-traits")]
483const fn from_posix(err: posix_errno::Error) -> Option<Error> {
484 use posix_errno::Error as P;
485 match err {
486 P::E2BIG => Some(target::E2BIG),
487 P::EACCES => Some(target::EACCES),
488 P::EADDRINUSE => Some(target::EADDRINUSE),
489 P::EADDRNOTAVAIL => Some(target::EADDRNOTAVAIL),
490 P::EAFNOSUPPORT => Some(target::EAFNOSUPPORT),
491 P::EAGAIN => Some(target::EAGAIN),
492 P::EALREADY => Some(target::EALREADY),
493 P::EBADF => Some(target::EBADF),
494 P::EBADMSG => Some(target::EBADMSG),
495 P::EBUSY => Some(target::EBUSY),
496 P::ECANCELED => Some(target::ECANCELED),
497 P::ECHILD => Some(target::ECHILD),
498 P::ECONNABORTED => Some(target::ECONNABORTED),
499 P::ECONNREFUSED => Some(target::ECONNREFUSED),
500 P::ECONNRESET => Some(target::ECONNRESET),
501 P::EDEADLK => Some(target::EDEADLK),
502 P::EDESTADDRREQ => Some(target::EDESTADDRREQ),
503 P::EDOM => Some(target::EDOM),
504 P::EDQUOT => Some(target::EDQUOT),
505 P::EEXIST => Some(target::EEXIST),
506 P::EFAULT => Some(target::EFAULT),
507 P::EFBIG => Some(target::EFBIG),
508 P::EHOSTUNREACH => Some(target::EHOSTUNREACH),
509 P::EIDRM => Some(target::EIDRM),
510 P::EILSEQ => Some(target::EILSEQ),
511 P::EINPROGRESS => Some(target::EINPROGRESS),
512 P::EINTR => Some(target::EINTR),
513 P::EINVAL => Some(target::EINVAL),
514 P::EIO => Some(target::EIO),
515 P::EISCONN => Some(target::EISCONN),
516 P::EISDIR => Some(target::EISDIR),
517 P::ELOOP => Some(target::ELOOP),
518 P::EMFILE => Some(target::EMFILE),
519 P::EMLINK => Some(target::EMLINK),
520 P::EMSGSIZE => Some(target::EMSGSIZE),
521 P::EMULTIHOP => Some(target::EMULTIHOP),
522 P::ENAMETOOLONG => Some(target::ENAMETOOLONG),
523 P::ENETDOWN => Some(target::ENETDOWN),
524 P::ENETRESET => Some(target::ENETRESET),
525 P::ENETUNREACH => Some(target::ENETUNREACH),
526 P::ENFILE => Some(target::ENFILE),
527 P::ENOBUFS => Some(target::ENOBUFS),
528 P::ENODATA => Some(target::ENODATA),
529 P::ENODEV => Some(target::ENODEV),
530 P::ENOENT => Some(target::ENOENT),
531 P::ENOEXEC => Some(target::ENOEXEC),
532 P::ENOLCK => Some(target::ENOLCK),
533 P::ENOLINK => Some(target::ENOLINK),
534 P::ENOMEM => Some(target::ENOMEM),
535 P::ENOMSG => Some(target::ENOMSG),
536 P::ENOPROTOOPT => Some(target::ENOPROTOOPT),
537 P::ENOSPC => Some(target::ENOSPC),
538 P::ENOSR => Some(target::ENOSR),
539 P::ENOSTR => Some(target::ENOSTR),
540 P::ENOSYS => Some(target::ENOSYS),
541 P::ENOTCONN => Some(target::ENOTCONN),
542 P::ENOTDIR => Some(target::ENOTDIR),
543 P::ENOTEMPTY => Some(target::ENOTEMPTY),
544 P::ENOTRECOVERABLE => Some(target::ENOTRECOVERABLE),
545 P::ENOTSOCK => Some(target::ENOTSOCK),
546 P::ENOTSUP => None,
547 P::ENOTTY => Some(target::ENOTTY),
548 P::ENXIO => Some(target::ENXIO),
549 P::EOPNOTSUPP => Some(target::EOPNOTSUPP),
550 P::EOVERFLOW => Some(target::EOVERFLOW),
551 P::EOWNERDEAD => Some(target::EOWNERDEAD),
552 P::EPERM => Some(target::EPERM),
553 P::EPIPE => Some(target::EPIPE),
554 P::EPROTO => Some(target::EPROTO),
555 P::EPROTONOSUPPORT => Some(target::EPROTONOSUPPORT),
556 P::EPROTOTYPE => Some(target::EPROTOTYPE),
557 P::ERANGE => Some(target::ERANGE),
558 P::EROFS => Some(target::EROFS),
559 P::ESPIPE => Some(target::ESPIPE),
560 P::ESRCH => Some(target::ESRCH),
561 P::ESTALE => Some(target::ESTALE),
562 P::ETIME => Some(target::ETIME),
563 P::ETIMEDOUT => Some(target::ETIMEDOUT),
564 P::ETXTBSY => Some(target::ETXTBSY),
565 P::EWOULDBLOCK => Some(target::EWOULDBLOCK),
566 P::EXDEV => Some(target::EXDEV),
567 _ => None,
568 }
569}
570
571#[cfg(any(feature = "posix-traits", doc))]
572impl PartialEq<posix_errno::Error> for Error {
573 #[inline]
574 fn eq(&self, other: &posix_errno::Error) -> bool {
575 from_posix(*other) == Some(*self)
576 }
577}
578
579#[cfg(any(feature = "posix-traits", doc))]
580impl PartialEq<Error> for posix_errno::Error {
581 #[inline]
582 fn eq(&self, other: &Error) -> bool {
583 from_posix(*self) == Some(*other)
584 }
585}