1#[derive(Debug)]
5#[non_exhaustive]
6pub enum Error<T> {
7 Io(T),
9 UnexpectedEof,
11 WriteZero,
13 InvalidInput,
15 NotFound,
17 AlreadyExists,
19 DirectoryIsNotEmpty,
21 CorruptedFileSystem,
23 NotEnoughSpace,
25 InvalidFileNameLength,
27 UnsupportedFileNameCharacter,
29}
30
31impl<T: IoError> From<T> for Error<T> {
32 fn from(error: T) -> Self {
33 Error::Io(error)
34 }
35}
36
37#[cfg(feature = "std")]
38impl From<Error<std::io::Error>> for std::io::Error {
39 fn from(error: Error<Self>) -> Self {
40 match error {
41 Error::Io(io_error) => io_error,
42 Error::UnexpectedEof | Error::NotEnoughSpace => Self::new(std::io::ErrorKind::UnexpectedEof, error),
43 Error::WriteZero => Self::new(std::io::ErrorKind::WriteZero, error),
44 Error::InvalidInput
45 | Error::InvalidFileNameLength
46 | Error::UnsupportedFileNameCharacter
47 | Error::DirectoryIsNotEmpty => Self::new(std::io::ErrorKind::InvalidInput, error),
48 Error::NotFound => Self::new(std::io::ErrorKind::NotFound, error),
49 Error::AlreadyExists => Self::new(std::io::ErrorKind::AlreadyExists, error),
50 Error::CorruptedFileSystem => Self::new(std::io::ErrorKind::InvalidData, error),
51 }
52 }
53}
54
55impl<T: core::fmt::Display> core::fmt::Display for Error<T> {
56 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57 match self {
58 Error::Io(io_error) => write!(f, "IO error: {}", io_error),
59 Error::UnexpectedEof => write!(f, "Unexpected end of file"),
60 Error::NotEnoughSpace => write!(f, "Not enough space"),
61 Error::WriteZero => write!(f, "Write zero"),
62 Error::InvalidInput => write!(f, "Invalid input"),
63 Error::InvalidFileNameLength => write!(f, "Invalid file name length"),
64 Error::UnsupportedFileNameCharacter => write!(f, "Unsupported file name character"),
65 Error::DirectoryIsNotEmpty => write!(f, "Directory is not empty"),
66 Error::NotFound => write!(f, "No such file or directory"),
67 Error::AlreadyExists => write!(f, "File or directory already exists"),
68 Error::CorruptedFileSystem => write!(f, "Corrupted file system"),
69 }
70 }
71}
72
73#[cfg(feature = "std")]
74impl<T: std::error::Error + 'static> std::error::Error for Error<T> {
75 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76 if let Error::Io(io_error) = self {
77 Some(io_error)
78 } else {
79 None
80 }
81 }
82}
83
84pub trait IoError: core::fmt::Debug {
88 fn is_interrupted(&self) -> bool;
89 fn new_unexpected_eof_error() -> Self;
90 fn new_write_zero_error() -> Self;
91}
92
93impl<T: core::fmt::Debug + IoError> IoError for Error<T> {
94 fn is_interrupted(&self) -> bool {
95 match self {
96 Error::<T>::Io(io_error) => io_error.is_interrupted(),
97 _ => false,
98 }
99 }
100
101 fn new_unexpected_eof_error() -> Self {
102 Error::<T>::UnexpectedEof
103 }
104
105 fn new_write_zero_error() -> Self {
106 Error::<T>::WriteZero
107 }
108}
109
110impl IoError for () {
111 fn is_interrupted(&self) -> bool {
112 false
113 }
114
115 fn new_unexpected_eof_error() -> Self {
116 }
118
119 fn new_write_zero_error() -> Self {
120 }
122}
123
124#[cfg(feature = "std")]
125impl IoError for std::io::Error {
126 fn is_interrupted(&self) -> bool {
127 self.kind() == std::io::ErrorKind::Interrupted
128 }
129
130 fn new_unexpected_eof_error() -> Self {
131 Self::new(std::io::ErrorKind::UnexpectedEof, "failed to fill whole buffer")
132 }
133
134 fn new_write_zero_error() -> Self {
135 Self::new(std::io::ErrorKind::WriteZero, "failed to write whole buffer")
136 }
137}