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}