1use core::fmt::Debug;
2
3#[allow(dead_code)]
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[repr(u16)]
6pub enum ErrorStatus {
7 Generic = 1,
9 OperationNotSupported = 2,
10 NotSupported = 3,
13 Corrupted = 4,
15 InvalidSyscall = 5,
16 UnknownResource = 6,
18 InvalidPid = 7,
19 InvalidOffset = 8,
20 InvalidPtr = 9,
23 InvalidStr = 0xA,
25 StrTooLong = 0xB,
28 InvalidPath = 0xC,
29 NoSuchAFileOrDirectory = 0xD,
30 NotAFile = 0xE,
31 NotADirectory = 0xF,
32 AlreadyExists = 0x10,
33 NotExecutable = 0x11,
34 DirectoryNotEmpty = 0x12,
35 MissingPermissions = 0x13,
37 MMapError = 0x14,
39 Busy = 0x15,
40 NotEnoughArguments = 0x16,
42 OutOfMemory = 0x17,
43 InvalidTid = 0x18,
45 Timeout = 0x19,
47 InvalidCommand = 0x1A,
49 InvalidArgument = 0x1B,
51 Unknown = 0x1C,
53 Panic = 0x1D,
55 NotADevice = 0x1E,
57 WouldBlock = 0x1F,
59 ConnectionClosed = 0x20,
61 ConnectionRefused = 0x21,
63 UnsupportedResource = 0x22,
65 ResourceCloneFailed = 0x23,
67 TypeMismatch = 0x24,
71 TooShort = 0x25,
73 AddressNotFound = 0x26,
75 InvalidSize = 0x27,
77 ForceTerminated = 0x28,
79 AddressAlreadyInUse = 0x29,
81 NotBound = 0x2A,
83}
84
85impl ErrorStatus {
86 const MAX: u16 = Self::NotBound as u16;
88
89 #[inline(always)]
90 pub fn as_str(&self) -> &'static str {
92 use ErrorStatus::*;
93 match *self {
94 InvalidSize => "Invalid Size",
95 AddressNotFound => "Address Not Found",
96 TooShort => "Too Short",
97 Generic => "Generic Error",
98 OperationNotSupported => "Operation Not Supported",
99 NotSupported => "Object Not Supported",
100 Corrupted => "Corrupted",
101 InvalidSyscall => "Invalid Syscall",
102 UnknownResource => "Unknown Resource ID",
103 UnsupportedResource => "Resource not supported by that Operation",
104 ResourceCloneFailed => "Failed to clone Resource",
105 TypeMismatch => "Type Mismatch",
106 InvalidPid => "Invalid PID",
107 InvalidTid => "Invalid TID",
108 InvalidOffset => "Invalid Offset",
109 InvalidPtr => "Invalid Ptr (not aligned or null)",
110 InvalidStr => "Invalid Str (not utf8)",
111 StrTooLong => "Str too Long",
112 InvalidPath => "Invalid Path",
113 NoSuchAFileOrDirectory => "No Such a File or Directory",
114 NotAFile => "Not a File",
115 NotADirectory => "Not a Directory",
116 AlreadyExists => "Already Exists",
117 NotExecutable => "Not Executable",
118 DirectoryNotEmpty => "Directory not Empty",
119 MissingPermissions => "Missing Permissions",
120 MMapError => "Memory Map Error (most likely out of memory)",
121 Busy => "Resource Busy",
122 NotEnoughArguments => "Not Enough Arguments",
123 OutOfMemory => "Out of Memory",
124 InvalidArgument => "Invalid Argument",
125 InvalidCommand => "Invalid Command",
126 Unknown => "Operation Unknown",
127 Panic => "Unrecoverable Panick",
128 Timeout => "Operation Timeouted",
129 NotADevice => "Not A Device",
130 ConnectionClosed => "Connection Closed",
131 ConnectionRefused => "Connection Refused",
132 WouldBlock => "Operation Would Block",
133 ForceTerminated => "Operation Terminated",
134 AddressAlreadyInUse => "Address Already In Use",
135 NotBound => "Interface Not Bound",
136 }
137 }
138
139 pub const fn try_from_u16(value: u16) -> Result<Self, ()> {
141 if value > 0 && value <= Self::MAX {
142 Ok(unsafe { core::mem::transmute(value) })
143 } else {
144 Err(())
145 }
146 }
147 pub const fn from_u16(value: u16) -> Self {
149 match Self::try_from_u16(value) {
151 Ok(k) => k,
152 Err(()) => Self::Unknown,
153 }
154 }
155}
156
157impl TryFrom<u16> for ErrorStatus {
158 type Error = ();
159
160 fn try_from(value: u16) -> Result<Self, Self::Error> {
161 Self::try_from_u16(value)
162 }
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
167#[repr(transparent)]
168pub struct SysResult(isize);
169
170impl SysResult {
171 pub const fn err(err: ErrorStatus) -> Self {
173 Self(-(err as isize))
174 }
175
176 pub const fn into_result(self) -> Result<usize, ErrorStatus> {
178 if self.0.is_negative() {
179 Err(ErrorStatus::from_u16((-self.0) as u16))
180 } else {
181 Ok(self.0 as usize)
182 }
183 }
184
185 pub const fn try_from_result(result: Result<usize, ErrorStatus>) -> Result<Self, ()> {
187 match result {
188 Err(err) => Ok(Self::err(err)),
189 Ok(value) => Self::try_ok(value),
190 }
191 }
192
193 pub const fn ok(value: usize) -> Self {
195 let Ok(ok) = Self::try_ok(value) else {
196 panic!("Attempt to construct an Ok SysResult value larger than isize::MAX")
197 };
198 ok
199 }
200
201 pub const fn try_ok(value: usize) -> Result<Self, ()> {
203 let value = value as isize;
204 if value.is_negative() {
205 return Err(());
206 }
207
208 Ok(Self(value))
209 }
210
211 pub const fn as_isize(&self) -> isize {
213 self.0
214 }
215
216 pub const fn from_isize(isize: isize) -> Self {
220 Self(isize)
221 }
222}
223
224impl From<ErrorStatus> for SysResult {
225 #[inline(always)]
226 fn from(value: ErrorStatus) -> Self {
227 Self::err(value)
228 }
229}
230
231impl From<Result<usize, ErrorStatus>> for SysResult {
232 #[inline(always)]
234 fn from(value: Result<usize, ErrorStatus>) -> Self {
235 Self::try_from_result(value).expect("Ok value is bigger than isize::MAX")
236 }
237}
238
239impl From<SysResult> for Result<usize, ErrorStatus> {
240 #[inline(always)]
241 fn from(value: SysResult) -> Self {
242 value.into_result()
243 }
244}
245
246impl Into<isize> for SysResult {
247 #[inline(always)]
248 fn into(self) -> isize {
249 self.0
250 }
251}
252
253impl From<isize> for SysResult {
254 fn from(value: isize) -> Self {
255 Self::from_isize(value)
256 }
257}
258
259pub trait IntoErr {
260 fn into_err(self) -> ErrorStatus;
261}
262
263impl<T: IntoErr> From<T> for ErrorStatus {
264 fn from(value: T) -> Self {
265 value.into_err()
266 }
267}
268
269impl From<core::str::Utf8Error> for ErrorStatus {
270 fn from(value: core::str::Utf8Error) -> Self {
271 match value {
272 core::str::Utf8Error { .. } => Self::InvalidStr,
273 }
274 }
275}
276
277#[cfg(feature = "std")]
278mod std_only {
279 use super::SysResult;
280 use std::process::ExitCode;
281 use std::process::Termination;
282 impl Termination for SysResult {
283 fn report(self) -> ExitCode {
284 let u16: u16 = match self.into_result() {
285 Ok(_) => 0,
286 Err(smth) => smth as u16,
287 };
288 ExitCode::from(u16 as u8)
289 }
290 }
291}