1use core::{fmt::Display, num::NonZeroU32};
7
8pub type Result<T> = core::result::Result<T, Error>;
28
29#[derive(Debug, PartialEq, Clone, Copy, Eq)]
35#[repr(C)]
36pub enum Error {
37 FailedToInitializeFileSystem = 1,
39 PermissionDenied,
41 NotFound,
43 AlreadyExists,
45 DirectoryAlreadyExists,
47 FileSystemFull,
49 FileSystemError,
51 InvalidPath,
53 InvalidFile,
55 InvalidDirectory,
57 InvalidSymbolicLink,
59 Unknown,
61 InvalidIdentifier,
63 FailedToGetTaskInformations,
65 FailedToGetUsersInformations,
67 TooManyMountedFileSystems,
69 TooManyOpenFiles,
71 InternalError,
73 InvalidMode,
75 UnsupportedOperation,
77 RessourceBusy,
79 AlreadyInitialized,
81 NotInitialized,
83 FailedToGetUsersManagerInstance,
85 FailedToGetTaskManagerInstance,
87 InvalidParameter,
89 InvalidFlags,
91 NotDirectory,
93 IsDirectory,
95 InputOutput,
97 DirectoryNotEmpty,
99 FileTooLarge,
101 NoAttribute,
103 NameTooLong,
105 Corrupted,
107 NoMemory,
109 NoSpaceLeft,
111 TimeError,
113 InvalidInode,
115 Other,
117}
118
119impl Error {
120 pub fn get_discriminant(&self) -> NonZeroU32 {
140 unsafe { NonZeroU32::new_unchecked(*self as u32) }
141 }
142}
143
144impl From<task::Error> for Error {
148 fn from(_: task::Error) -> Self {
149 Error::FailedToGetTaskInformations
150 }
151}
152
153impl From<users::Error> for Error {
157 fn from(_: users::Error) -> Self {
158 Error::FailedToGetUsersInformations
159 }
160}
161
162impl From<Error> for NonZeroU32 {
166 fn from(error: Error) -> Self {
167 error.get_discriminant()
168 }
169}
170
171impl Display for Error {
175 fn fmt(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
176 let string = match self {
177 Error::FailedToInitializeFileSystem => "Failed to initialize file system",
178 Error::PermissionDenied => "Permission denied",
179 Error::NotFound => "Not found",
180 Error::AlreadyExists => "Already exists",
181 Error::DirectoryAlreadyExists => "Directory already exists",
182 Error::FileSystemFull => "File system full",
183 Error::FileSystemError => "File system error",
184 Error::InvalidPath => "Invalid path",
185 Error::InvalidFile => "Invalid file",
186 Error::InvalidDirectory => "Invalid directory",
187 Error::InvalidSymbolicLink => "Invalid symbolic link",
188 Error::Unknown => "Unknown",
189 Error::InvalidIdentifier => "Invalid identifier",
190 Error::FailedToGetTaskInformations => "Failed to get task informations",
191 Error::FailedToGetUsersInformations => "Failed to get users informations",
192 Error::TooManyMountedFileSystems => "Too many mounted file systems",
193 Error::TooManyOpenFiles => "Too many open files",
194 Error::InternalError => "Internal error",
195 Error::InvalidMode => "Invalid mode",
196 Error::UnsupportedOperation => "Unsupported operation",
197 Error::RessourceBusy => "Ressource busy",
198 Error::AlreadyInitialized => "Already initialized",
199 Error::NotInitialized => "Not initialized",
200 Error::FailedToGetUsersManagerInstance => "Failed to get users manager instance",
201 Error::FailedToGetTaskManagerInstance => "Failed to get task manager instance",
202 Error::InvalidParameter => "Invalid parameter",
203 Error::InvalidFlags => "Invalid flags",
204 Error::NotDirectory => "Not directory",
205 Error::IsDirectory => "Is directory",
206 Error::InputOutput => "Input output",
207 Error::DirectoryNotEmpty => "Directory not empty",
208 Error::FileTooLarge => "File too large",
209 Error::NoAttribute => "No attribute",
210 Error::NameTooLong => "Name too long",
211 Error::Corrupted => "Corrupted",
212 Error::NoMemory => "No memory",
213 Error::NoSpaceLeft => "No space left",
214 Error::TimeError => "Time error",
215 Error::InvalidInode => "Invalid inode",
216 Error::Other => "Other",
217 };
218
219 write!(formatter, "{string}")
220 }
221}
222
223#[cfg(test)]
224mod tests {
225 use super::*;
226 use alloc::format;
227
228 #[test]
229 fn test_error_discriminants() {
230 assert_eq!(
232 Error::FailedToInitializeFileSystem.get_discriminant().get(),
233 1
234 );
235 assert_eq!(Error::PermissionDenied.get_discriminant().get(), 2);
236 assert_eq!(Error::NotFound.get_discriminant().get(), 3);
237 assert_eq!(Error::AlreadyExists.get_discriminant().get(), 4);
238 assert_eq!(Error::DirectoryAlreadyExists.get_discriminant().get(), 5);
239
240 assert_eq!(Error::FileSystemFull.get_discriminant().get(), 6);
242 assert_eq!(Error::FileSystemError.get_discriminant().get(), 7);
243 assert_eq!(Error::InvalidPath.get_discriminant().get(), 8);
244 }
245
246 #[test]
247 fn test_error_display() {
248 assert_eq!(
250 format!("{}", Error::FailedToInitializeFileSystem),
251 "Failed to initialize file system"
252 );
253 assert_eq!(format!("{}", Error::PermissionDenied), "Permission denied");
254 assert_eq!(format!("{}", Error::NotFound), "Not found");
255 assert_eq!(format!("{}", Error::AlreadyExists), "Already exists");
256 assert_eq!(
257 format!("{}", Error::DirectoryAlreadyExists),
258 "Directory already exists"
259 );
260 assert_eq!(format!("{}", Error::FileSystemFull), "File system full");
261 assert_eq!(format!("{}", Error::FileSystemError), "File system error");
262 assert_eq!(format!("{}", Error::InvalidPath), "Invalid path");
263 assert_eq!(format!("{}", Error::InvalidFile), "Invalid file");
264 assert_eq!(format!("{}", Error::InvalidDirectory), "Invalid directory");
265 assert_eq!(
266 format!("{}", Error::InvalidSymbolicLink),
267 "Invalid symbolic link"
268 );
269 assert_eq!(format!("{}", Error::Unknown), "Unknown");
270 assert_eq!(
271 format!("{}", Error::InvalidIdentifier),
272 "Invalid identifier"
273 );
274 assert_eq!(
275 format!("{}", Error::FailedToGetTaskInformations),
276 "Failed to get task informations"
277 );
278 assert_eq!(
279 format!("{}", Error::FailedToGetUsersInformations),
280 "Failed to get users informations"
281 );
282 assert_eq!(
283 format!("{}", Error::TooManyMountedFileSystems),
284 "Too many mounted file systems"
285 );
286 assert_eq!(
287 format!("{}", Error::TooManyOpenFiles),
288 "Too many open files"
289 );
290 assert_eq!(format!("{}", Error::InternalError), "Internal error");
291 assert_eq!(format!("{}", Error::InvalidMode), "Invalid mode");
292 assert_eq!(
293 format!("{}", Error::UnsupportedOperation),
294 "Unsupported operation"
295 );
296 assert_eq!(format!("{}", Error::RessourceBusy), "Ressource busy");
297 assert_eq!(
298 format!("{}", Error::AlreadyInitialized),
299 "Already initialized"
300 );
301 assert_eq!(format!("{}", Error::NotInitialized), "Not initialized");
302 assert_eq!(
303 format!("{}", Error::FailedToGetUsersManagerInstance),
304 "Failed to get users manager instance"
305 );
306 assert_eq!(
307 format!("{}", Error::FailedToGetTaskManagerInstance),
308 "Failed to get task manager instance"
309 );
310 assert_eq!(format!("{}", Error::InvalidParameter), "Invalid parameter");
311 assert_eq!(format!("{}", Error::InvalidFlags), "Invalid flags");
312 assert_eq!(format!("{}", Error::NotDirectory), "Not directory");
313 assert_eq!(format!("{}", Error::IsDirectory), "Is directory");
314 assert_eq!(format!("{}", Error::InputOutput), "Input output");
315 assert_eq!(
316 format!("{}", Error::DirectoryNotEmpty),
317 "Directory not empty"
318 );
319 assert_eq!(format!("{}", Error::FileTooLarge), "File too large");
320 assert_eq!(format!("{}", Error::NoAttribute), "No attribute");
321 assert_eq!(format!("{}", Error::NameTooLong), "Name too long");
322 assert_eq!(format!("{}", Error::Corrupted), "Corrupted");
323 assert_eq!(format!("{}", Error::NoMemory), "No memory");
324 assert_eq!(format!("{}", Error::NoSpaceLeft), "No space left");
325 assert_eq!(format!("{}", Error::TimeError), "Time error");
326 assert_eq!(format!("{}", Error::InvalidInode), "Invalid inode");
327 assert_eq!(format!("{}", Error::Other), "Other");
328 }
329
330 #[test]
331 fn test_error_debug() {
332 let error = Error::PermissionDenied;
334 let debug_str = format!("{error:?}");
335 assert_eq!(debug_str, "Permission_denied");
336 }
337
338 #[test]
339 fn test_error_equality() {
340 let error1 = Error::NotFound;
342 let error2 = Error::NotFound;
343 let error3 = Error::PermissionDenied;
344
345 assert_eq!(error1, error2);
346 assert_ne!(error1, error3);
347
348 let cloned = error1;
349 assert_eq!(error1, cloned);
350 }
351
352 #[test]
353 fn test_error_conversions() {
354 let error = Error::NotFound;
356 let discriminant: NonZeroU32 = error.into();
357 assert_eq!(discriminant.get(), 3);
358
359 assert_eq!(error.get_discriminant().get(), 3);
361 }
362
363 #[test]
364 fn test_result_type() {
365 let success: Result<i32> = Ok(42);
367 let failure: Result<i32> = Err(Error::PermissionDenied);
368
369 assert_eq!(success, Ok(42));
370
371 assert_eq!(failure, Err(Error::PermissionDenied));
372 }
373
374 #[test]
375 fn test_error_categories() {
376 assert!(matches!(
380 Error::FailedToInitializeFileSystem.get_discriminant().get(),
381 1
382 ));
383 assert!(matches!(
384 Error::AlreadyInitialized.get_discriminant().get(),
385 22
386 ));
387 assert!(matches!(Error::NotInitialized.get_discriminant().get(), 23));
388
389 assert!(matches!(
391 Error::PermissionDenied.get_discriminant().get(),
392 2
393 ));
394 assert!(matches!(Error::InvalidMode.get_discriminant().get(), 19));
395
396 assert!(matches!(Error::NotFound.get_discriminant().get(), 3));
398 assert!(matches!(Error::AlreadyExists.get_discriminant().get(), 4));
399 assert!(matches!(
400 Error::DirectoryAlreadyExists.get_discriminant().get(),
401 5
402 ));
403 }
404
405 #[test]
406 fn test_error_copy_semantics() {
407 let error = Error::FileSystemFull;
409 let copied = error; assert_eq!(error, Error::FileSystemFull);
413 assert_eq!(copied, Error::FileSystemFull);
414 assert_eq!(error, copied);
415 }
416
417 #[test]
418 fn test_error_size() {
419 use core::mem::size_of;
421
422 assert!(size_of::<Error>() <= 4); }
425
426 #[test]
427 fn test_nonzero_conversion() {
428 let errors = [
430 Error::FailedToInitializeFileSystem,
431 Error::PermissionDenied,
432 Error::NotFound,
433 Error::AlreadyExists,
434 Error::DirectoryAlreadyExists,
435 Error::FileSystemFull,
436 Error::FileSystemError,
437 Error::InvalidPath,
438 Error::InvalidFile,
439 Error::InvalidDirectory,
440 Error::InvalidSymbolicLink,
441 Error::Unknown,
442 Error::InvalidIdentifier,
443 Error::FailedToGetTaskInformations,
444 Error::FailedToGetUsersInformations,
445 Error::TooManyMountedFileSystems,
446 Error::TooManyOpenFiles,
447 Error::InternalError,
448 Error::InvalidMode,
449 Error::UnsupportedOperation,
450 Error::RessourceBusy,
451 Error::AlreadyInitialized,
452 Error::NotInitialized,
453 Error::FailedToGetUsersManagerInstance,
454 Error::FailedToGetTaskManagerInstance,
455 Error::InvalidParameter,
456 Error::InvalidFlags,
457 Error::NotDirectory,
458 Error::IsDirectory,
459 Error::InputOutput,
460 Error::DirectoryNotEmpty,
461 Error::FileTooLarge,
462 Error::NoAttribute,
463 Error::NameTooLong,
464 Error::Corrupted,
465 Error::NoMemory,
466 Error::NoSpaceLeft,
467 Error::TimeError,
468 Error::InvalidInode,
469 Error::Other,
470 ];
471
472 for error in errors.iter() {
473 let discriminant = error.get_discriminant();
474 assert!(discriminant.get() > 0);
475
476 let converted: NonZeroU32 = (*error).into();
477 assert_eq!(discriminant, converted);
478 }
479 }
480}