Skip to main content

virtual_file_system/
error.rs

1use core::{fmt::Display, num::NonZeroU32};
2
3use embedded_io_async::ErrorKind;
4use internationalization::translate;
5
6pub type Result<T> = core::result::Result<T, Error>;
7
8#[derive(Debug, PartialEq, Clone, Copy, Eq)]
9#[repr(u32)]
10pub enum Error {
11    AlreadyInitialized = 1,
12    UnavailableDriver,
13    InvalidFileSystem,
14    InvalidParameter,
15    TooManyOpenFiles,
16    FailedToGetTaskInformations,
17    InvalidIdentifier,
18    AlreadyExists,
19    Time(time::Error),
20    FileSystem(file_system::Error) = 0x100,
21    Users(users::Error) = 0x300,
22    Task(task::Error) = 0x400,
23    MissingAttribute,
24    InvalidPath,
25    PermissionDenied,
26    TooManyInodes,
27    RessourceBusy,
28    NotADirectory,
29    NotAFile,
30    InvalidInode,
31    InvalidMode,
32    InvalidOpen,
33    UnsupportedOperation,
34    FailedToWrite,
35    DelimiterNotFound,
36    Orphaned,
37}
38
39impl Error {
40    pub fn get_discriminant(&self) -> NonZeroU32 {
41        unsafe { *<*const _>::from(self).cast::<NonZeroU32>() }
42    }
43}
44
45impl From<Error> for NonZeroU32 {
46    fn from(value: Error) -> Self {
47        let discriminant = value.get_discriminant();
48
49        let offset = match value {
50            Error::FileSystem(error_type) => error_type.get_discriminant().get(),
51            _ => 0,
52        };
53
54        discriminant.saturating_add(offset)
55    }
56}
57
58impl From<users::Error> for Error {
59    fn from(value: users::Error) -> Self {
60        Self::Users(value)
61    }
62}
63
64impl From<time::Error> for Error {
65    fn from(value: time::Error) -> Self {
66        Self::Time(value)
67    }
68}
69
70impl From<file_system::Error> for Error {
71    fn from(value: file_system::Error) -> Self {
72        Self::FileSystem(value)
73    }
74}
75
76impl From<task::Error> for Error {
77    fn from(value: task::Error) -> Self {
78        Self::Task(value)
79    }
80}
81
82impl Display for Error {
83    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84        match self {
85            Error::AlreadyInitialized => write!(f, translate!("Already initialized")),
86            Error::UnavailableDriver => write!(f, translate!("Unavailable driver")),
87            Error::InvalidFileSystem => write!(f, translate!("Invalid file system")),
88            Error::InvalidParameter => write!(f, translate!("Invalid parameter")),
89            Error::TooManyOpenFiles => write!(f, translate!("Too many open files")),
90            Error::FailedToGetTaskInformations => {
91                write!(f, translate!("Failed to get task informations"))
92            }
93            Error::FileSystem(err) => write!(f, translate!("File system error: {}"), err),
94            Error::InvalidIdentifier => write!(f, translate!("Invalid identifier")),
95            Error::AlreadyExists => write!(f, translate!("Already exists")),
96            Error::Time(err) => write!(f, translate!("Time error: {}"), err),
97            Error::Users(err) => write!(f, translate!("Users error: {}"), err),
98            Error::Task(err) => write!(f, translate!("Task error: {}"), err),
99            Error::MissingAttribute => write!(f, translate!("Missing attribute")),
100            Error::InvalidPath => write!(f, translate!("Invalid path")),
101            Error::PermissionDenied => write!(f, translate!("Permission denied")),
102            Error::TooManyInodes => write!(f, translate!("Too many inodes")),
103            Error::RessourceBusy => write!(f, translate!("Ressource busy")),
104            Error::NotADirectory => write!(f, translate!("Not a directory")),
105            Error::NotAFile => write!(f, translate!("Not a file")),
106            Error::InvalidMode => write!(f, translate!("Invalid mode")),
107            Error::InvalidOpen => write!(f, translate!("Invalid open")),
108            Error::InvalidInode => write!(f, translate!("Invalid inode")),
109            Error::UnsupportedOperation => write!(f, translate!("Unsupported operation")),
110            Error::FailedToWrite => write!(f, translate!("Failed to write")),
111            Error::DelimiterNotFound => write!(f, translate!("Delimiter not found")),
112            Error::Orphaned => write!(f, translate!("Orphaned")),
113        }
114    }
115}
116
117impl core::error::Error for Error {}
118
119impl embedded_io_async::Error for Error {
120    fn kind(&self) -> ErrorKind {
121        match self {
122            Error::PermissionDenied => ErrorKind::PermissionDenied,
123            Error::NotADirectory => ErrorKind::InvalidInput,
124            Error::NotAFile => ErrorKind::InvalidInput,
125            Error::InvalidMode => ErrorKind::InvalidInput,
126            Error::InvalidOpen => ErrorKind::InvalidInput,
127            Error::UnsupportedOperation => ErrorKind::Unsupported,
128            _ => ErrorKind::Other,
129        }
130    }
131}