1use core::fmt;
4
5#[derive(Debug)]
7pub enum FatError {
8 InvalidBootSignature {
10 found: u16,
12 },
13 UnsupportedFatType(&'static str),
15 InvalidFsInfoSignature {
17 field: &'static str,
19 expected: u32,
21 found: u32,
23 },
24 InvalidShortFilename,
26 ClusterOutOfBounds {
28 cluster: u32,
30 max: u32,
32 },
33 BadCluster {
35 cluster: u32,
37 },
38 UnexpectedEndOfChain {
40 cluster: u32,
42 },
43 Io(hadris_io::Error),
45 NotAFile,
47 NotADirectory,
49 EntryNotFound,
51 InvalidPath,
53 #[cfg(feature = "write")]
55 NoFreeSpace,
56 #[cfg(feature = "write")]
58 DirectoryFull,
59 #[cfg(feature = "write")]
61 InvalidFilename,
62 #[cfg(feature = "write")]
64 AlreadyExists,
65 #[cfg(feature = "write")]
67 DirectoryNotEmpty,
68
69 #[cfg(feature = "write")]
71 VolumeTooSmall {
72 size: u64,
74 min_size: u64,
76 },
77
78 #[cfg(feature = "write")]
80 VolumeTooLarge {
81 size: u64,
83 max_size: u64,
85 },
86
87 #[cfg(feature = "write")]
89 InvalidFormatOption {
90 option: &'static str,
92 reason: &'static str,
94 },
95
96 #[cfg(feature = "exfat")]
99 ExFatInvalidSignature {
100 expected: [u8; 8],
102 found: [u8; 8],
104 },
105 #[cfg(feature = "exfat")]
107 ExFatInvalidBootSector {
108 reason: &'static str,
110 },
111 #[cfg(feature = "exfat")]
113 ExFatInvalidChecksum {
114 expected: u32,
116 found: u32,
118 },
119 #[cfg(feature = "exfat")]
121 ExFatInvalidEntry {
122 reason: &'static str,
124 },
125}
126
127impl fmt::Display for FatError {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 Self::InvalidBootSignature { found } => {
131 write!(
132 f,
133 "invalid boot signature: expected 0xAA55, found {found:#06x}"
134 )
135 }
136 Self::UnsupportedFatType(ty) => {
137 write!(f, "unsupported FAT type: {ty}")
138 }
139 Self::InvalidFsInfoSignature {
140 field,
141 expected,
142 found,
143 } => {
144 write!(
145 f,
146 "invalid FSInfo signature: {field} expected {expected:#010x}, found {found:#010x}"
147 )
148 }
149 Self::InvalidShortFilename => {
150 write!(f, "invalid short filename")
151 }
152 Self::ClusterOutOfBounds { cluster, max } => {
153 write!(f, "cluster {cluster} out of bounds (max: {max})")
154 }
155 Self::BadCluster { cluster } => {
156 write!(f, "bad cluster marker encountered at cluster {cluster}")
157 }
158 Self::UnexpectedEndOfChain { cluster } => {
159 write!(f, "unexpected end of cluster chain at cluster {cluster}")
160 }
161 Self::Io(e) => {
162 write!(f, "I/O error: {e:?}")
163 }
164 Self::NotAFile => {
165 write!(f, "entry is not a file")
166 }
167 Self::NotADirectory => {
168 write!(f, "entry is not a directory")
169 }
170 Self::EntryNotFound => {
171 write!(f, "entry not found in directory")
172 }
173 Self::InvalidPath => {
174 write!(f, "path is invalid (empty or malformed)")
175 }
176 #[cfg(feature = "write")]
177 Self::NoFreeSpace => {
178 write!(f, "no free clusters available")
179 }
180 #[cfg(feature = "write")]
181 Self::DirectoryFull => {
182 write!(f, "directory is full (no free entry slots)")
183 }
184 #[cfg(feature = "write")]
185 Self::InvalidFilename => {
186 write!(f, "filename is invalid or too long")
187 }
188 #[cfg(feature = "write")]
189 Self::AlreadyExists => {
190 write!(f, "entry with this name already exists")
191 }
192 #[cfg(feature = "write")]
193 Self::DirectoryNotEmpty => {
194 write!(f, "cannot delete non-empty directory")
195 }
196 #[cfg(feature = "write")]
197 Self::VolumeTooSmall { size, min_size } => {
198 write!(
199 f,
200 "volume size {} bytes is too small (minimum: {} bytes)",
201 size, min_size
202 )
203 }
204 #[cfg(feature = "write")]
205 Self::VolumeTooLarge { size, max_size } => {
206 write!(
207 f,
208 "volume size {} bytes is too large (maximum: {} bytes)",
209 size, max_size
210 )
211 }
212 #[cfg(feature = "write")]
213 Self::InvalidFormatOption { option, reason } => {
214 write!(f, "invalid format option '{}': {}", option, reason)
215 }
216 #[cfg(feature = "exfat")]
217 Self::ExFatInvalidSignature { expected, found } => {
218 write!(
219 f,
220 "invalid exFAT signature: expected {:?}, found {:?}",
221 core::str::from_utf8(expected).unwrap_or("<invalid>"),
222 core::str::from_utf8(found).unwrap_or("<invalid>")
223 )
224 }
225 #[cfg(feature = "exfat")]
226 Self::ExFatInvalidBootSector { reason } => {
227 write!(f, "invalid exFAT boot sector: {reason}")
228 }
229 #[cfg(feature = "exfat")]
230 Self::ExFatInvalidChecksum { expected, found } => {
231 write!(
232 f,
233 "invalid exFAT checksum: expected {expected:#010x}, found {found:#010x}"
234 )
235 }
236 #[cfg(feature = "exfat")]
237 Self::ExFatInvalidEntry { reason } => {
238 write!(f, "invalid exFAT directory entry: {reason}")
239 }
240 }
241 }
242}
243
244#[cfg(feature = "std")]
245impl std::error::Error for FatError {}
246
247impl From<hadris_io::Error> for FatError {
248 fn from(e: hadris_io::Error) -> Self {
249 Self::Io(e)
250 }
251}
252
253pub type Result<T> = core::result::Result<T, FatError>;