Skip to main content

virtual_file_system/
error.rs

1use core::{fmt::Display, num::NonZeroU32};
2
3use embedded_i18n::translate;
4use embedded_io_async::ErrorKind;
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 u32 {
46    fn from(value: Error) -> Self {
47        NonZeroU32::from(value).get()
48    }
49}
50
51impl From<Error> for NonZeroU32 {
52    fn from(value: Error) -> Self {
53        let discriminant = value.get_discriminant();
54
55        let offset = match value {
56            Error::FileSystem(error_type) => error_type.get_discriminant().get(),
57            _ => 0,
58        };
59
60        discriminant.saturating_add(offset)
61    }
62}
63
64impl From<users::Error> for Error {
65    fn from(value: users::Error) -> Self {
66        Self::Users(value)
67    }
68}
69
70impl From<time::Error> for Error {
71    fn from(value: time::Error) -> Self {
72        Self::Time(value)
73    }
74}
75
76impl From<file_system::Error> for Error {
77    fn from(value: file_system::Error) -> Self {
78        Self::FileSystem(value)
79    }
80}
81
82impl From<task::Error> for Error {
83    fn from(value: task::Error) -> Self {
84        Self::Task(value)
85    }
86}
87
88impl Display for Error {
89    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90        match self {
91            Error::AlreadyInitialized => write!(f, translate!("Already initialized")),
92            Error::UnavailableDriver => write!(f, translate!("Unavailable driver")),
93            Error::InvalidFileSystem => write!(f, translate!("Invalid file system")),
94            Error::InvalidParameter => write!(f, translate!("Invalid parameter")),
95            Error::TooManyOpenFiles => write!(f, translate!("Too many open files")),
96            Error::FailedToGetTaskInformations => {
97                write!(f, translate!("Failed to get task informations"))
98            }
99            Error::FileSystem(err) => write!(f, translate!("File system error: {}"), err),
100            Error::InvalidIdentifier => write!(f, translate!("Invalid identifier")),
101            Error::AlreadyExists => write!(f, translate!("Already exists")),
102            Error::Time(err) => write!(f, translate!("Time error: {}"), err),
103            Error::Users(err) => write!(f, translate!("Users error: {}"), err),
104            Error::Task(err) => write!(f, translate!("Task error: {}"), err),
105            Error::MissingAttribute => write!(f, translate!("Missing attribute")),
106            Error::InvalidPath => write!(f, translate!("Invalid path")),
107            Error::PermissionDenied => write!(f, translate!("Permission denied")),
108            Error::TooManyInodes => write!(f, translate!("Too many inodes")),
109            Error::RessourceBusy => write!(f, translate!("Ressource busy")),
110            Error::NotADirectory => write!(f, translate!("Not a directory")),
111            Error::NotAFile => write!(f, translate!("Not a file")),
112            Error::InvalidMode => write!(f, translate!("Invalid mode")),
113            Error::InvalidOpen => write!(f, translate!("Invalid open")),
114            Error::InvalidInode => write!(f, translate!("Invalid inode")),
115            Error::UnsupportedOperation => write!(f, translate!("Unsupported operation")),
116            Error::FailedToWrite => write!(f, translate!("Failed to write")),
117            Error::DelimiterNotFound => write!(f, translate!("Delimiter not found")),
118            Error::Orphaned => write!(f, translate!("Orphaned")),
119        }
120    }
121}
122
123impl core::error::Error for Error {}
124
125impl embedded_io_async::Error for Error {
126    fn kind(&self) -> ErrorKind {
127        match self {
128            Error::PermissionDenied => ErrorKind::PermissionDenied,
129            Error::NotADirectory => ErrorKind::InvalidInput,
130            Error::NotAFile => ErrorKind::InvalidInput,
131            Error::InvalidMode => ErrorKind::InvalidInput,
132            Error::InvalidOpen => ErrorKind::InvalidInput,
133            Error::UnsupportedOperation => ErrorKind::Unsupported,
134            _ => ErrorKind::Other,
135        }
136    }
137}