devela/sys/os/linux/
error.rs1use crate::{IoError, IoErrorKind, LINUX_ERRNO as ERRNO, LINUX_EXIT as EXIT, is};
7
8#[doc = crate::TAG_RESULT!()]
9pub type LinuxResult<T> = crate::Result<T, LinuxError>;
11
12#[doc = crate::TAG_ERROR_COMPOSITE!()]
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub enum LinuxError {
19 Sys(isize),
26 NoInput,
28 InvalidUtf8,
30 }
33macro_rules! match_linux_to_io {
34 ($self:ident) => {
35 match $self {
36 LinuxError::Sys(errno) => {
37 let kind = match errno {
38 ERRNO::EPERM => IoErrorKind::PermissionDenied,
39 ERRNO::ENOENT => IoErrorKind::NotFound,
40 ERRNO::EINTR => IoErrorKind::Interrupted,
41 ERRNO::EIO => IoErrorKind::Other,
42 ERRNO::ENXIO => IoErrorKind::NotFound,
43 ERRNO::EAGAIN => IoErrorKind::WouldBlock,
44 ERRNO::ENOMEM => IoErrorKind::OutOfMemory,
45 ERRNO::EACCES => IoErrorKind::PermissionDenied,
46 ERRNO::EFAULT => IoErrorKind::InvalidInput,
47 ERRNO::EBUSY => IoErrorKind::ResourceBusy,
48 ERRNO::EEXIST => IoErrorKind::AlreadyExists,
49 ERRNO::ENOTDIR => IoErrorKind::NotADirectory,
50 ERRNO::EISDIR => IoErrorKind::IsADirectory,
51 ERRNO::EINVAL => IoErrorKind::InvalidInput,
52 ERRNO::ENOSPC => IoErrorKind::StorageFull,
53 ERRNO::EROFS => IoErrorKind::ReadOnlyFilesystem,
54 ERRNO::EMLINK => IoErrorKind::TooManyLinks,
55 ERRNO::EPIPE => IoErrorKind::BrokenPipe,
56 ERRNO::EDOM => IoErrorKind::InvalidInput,
57 ERRNO::ERANGE => IoErrorKind::InvalidInput,
58 ERRNO::EDEADLK => IoErrorKind::Deadlock,
59 ERRNO::ENOLCK => IoErrorKind::ResourceBusy,
62 ERRNO::ENOSYS => IoErrorKind::Unsupported,
63 ERRNO::ENOTEMPTY => IoErrorKind::DirectoryNotEmpty,
64 ERRNO::ENODEV => IoErrorKind::NotFound,
67 ERRNO::ETIMEDOUT => IoErrorKind::TimedOut,
68 ERRNO::EXDEV => IoErrorKind::CrossesDevices,
69 ERRNO::ETXTBSY => IoErrorKind::ExecutableFileBusy,
70 _ => IoErrorKind::Other,
71 };
72 IoError::new(kind, "system call failed")
73 }
74 LinuxError::NoInput => IoError::new(IoErrorKind::UnexpectedEof, "no input available"),
75 LinuxError::InvalidUtf8 => IoError::new(IoErrorKind::InvalidData, "invalid UTF-8 data"),
76 }
77 };
78}
79macro_rules! match_io_to_linux {
80 ($err:ident) => {
81 match $err.kind() {
82 IoErrorKind::PermissionDenied => LinuxError::Sys(ERRNO::EACCES),
83 IoErrorKind::NotFound => LinuxError::Sys(ERRNO::ENOENT),
84 IoErrorKind::Interrupted => LinuxError::Sys(ERRNO::EINTR),
85 IoErrorKind::WouldBlock => LinuxError::Sys(ERRNO::EAGAIN),
86 IoErrorKind::OutOfMemory => LinuxError::Sys(ERRNO::ENOMEM),
87 IoErrorKind::InvalidInput => LinuxError::Sys(ERRNO::EINVAL),
88 IoErrorKind::StorageFull => LinuxError::Sys(ERRNO::ENOSPC),
89 IoErrorKind::BrokenPipe => LinuxError::Sys(ERRNO::EPIPE),
90 IoErrorKind::UnexpectedEof => LinuxError::NoInput,
91 IoErrorKind::InvalidData => LinuxError::InvalidUtf8,
92 _ => LinuxError::Sys(ERRNO::EIO), }
94 };
95}
96#[rustfmt::skip]
97impl LinuxError {
98 #[cfg(feature = "std")]
103 pub fn to_io(self) -> IoError { match_linux_to_io!(self) }
104 #[cfg(not(feature = "std"))]
106 pub const fn to_io(self) -> IoError { match_linux_to_io!(self) }
107
108 #[cfg(feature = "std")]
113 pub fn from_io(err: IoError) -> LinuxError { match_io_to_linux!(err) }
114 #[cfg(not(feature = "std"))]
116 pub const fn from_io(err: IoError) -> LinuxError { match_io_to_linux!(err) }
117}
118impl From<LinuxError> for IoError {
119 fn from(err: LinuxError) -> Self {
120 err.to_io()
121 }
122}
123impl From<IoError> for LinuxError {
124 fn from(err: IoError) -> Self {
125 LinuxError::from_io(err)
126 }
127}
128
129impl LinuxError {
130 pub const fn to_exit_code(self) -> i32 {
134 let code = self.to_raw_exit_code();
135 is![code >= EXIT::SUCCESS && code <= EXIT::MAX; code; EXIT::INTERNAL_ERROR]
136 }
137
138 pub const fn to_raw_exit_code(self) -> i32 {
140 match self {
141 LinuxError::Sys(errno) => {
142 match errno {
143 ERRNO::EPERM => EXIT::NOPERM,
144 ERRNO::ENOENT => EXIT::NOINPUT,
145 ERRNO::EACCES => EXIT::NOPERM,
146 ERRNO::EINVAL => EXIT::USAGE,
147 ERRNO::ENOSYS => EXIT::SOFTWARE,
148 ERRNO::ENOMEM => EXIT::OSERR,
149 ERRNO::EIO => EXIT::IOERR,
150 ERRNO::ENFILE | ERRNO::EMFILE => EXIT::OSFILE,
151 ERRNO::EEXIST => EXIT::CANTCREAT,
152 ERRNO::ENOTDIR => EXIT::DATAERR,
153 ERRNO::EISDIR => EXIT::DATAERR,
154 ERRNO::ETIMEDOUT => EXIT::TEMPFAIL,
155 _ => EXIT::OSERR,
157 }
158 }
159 LinuxError::NoInput => EXIT::NOINPUT,
160 LinuxError::InvalidUtf8 => EXIT::DATAERR,
161 }
162 }
163}