1use std::fmt;
4use std::io;
5
6pub type Result<T> = std::result::Result<T, Fat32Error>;
8
9#[derive(Debug)]
11pub enum Fat32Error {
12 Io(io::Error),
14
15 InvalidFat32 { message: String },
17
18 NotFound { path: String },
20
21 AlreadyExists { path: String },
23
24 NoFreeSpace,
26
27 InvalidFileName { name: String, reason: String },
29
30 PlatformError {
32 message: String,
33 #[cfg(windows)]
34 code: Option<u32>,
35 },
36
37 AccessDenied {
39 path: String,
40 tried_strategies: Vec<String>,
41 },
42
43 EspNotFound,
45}
46
47impl fmt::Display for Fat32Error {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 Self::Io(err) => write!(f, "I/O error: {}", err),
51 Self::InvalidFat32 { message } => write!(f, "Invalid FAT32: {}", message),
52 Self::NotFound { path } => write!(f, "Not found: {}", path),
53 Self::AlreadyExists { path } => write!(f, "Already exists: {}", path),
54 Self::NoFreeSpace => write!(f, "No free space available"),
55 Self::InvalidFileName { name, reason } => {
56 write!(f, "Invalid file name '{}': {}", name, reason)
57 }
58 Self::PlatformError { message, .. } => write!(f, "Platform error: {}", message),
59 Self::AccessDenied {
60 path,
61 tried_strategies,
62 } => {
63 write!(
64 f,
65 "Access denied for '{}'. Tried strategies: {:?}",
66 path, tried_strategies
67 )
68 }
69 Self::EspNotFound => write!(f, "ESP partition not found"),
70 }
71 }
72}
73
74impl std::error::Error for Fat32Error {
75 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
76 match self {
77 Self::Io(err) => Some(err),
78 _ => None,
79 }
80 }
81}
82
83impl From<io::Error> for Fat32Error {
84 fn from(err: io::Error) -> Self {
85 Self::Io(err)
86 }
87}
88
89impl Fat32Error {
91 pub fn invalid_fat32(message: impl Into<String>) -> Self {
92 Self::InvalidFat32 {
93 message: message.into(),
94 }
95 }
96
97 pub fn not_found(path: impl Into<String>) -> Self {
98 Self::NotFound { path: path.into() }
99 }
100
101 pub fn already_exists(path: impl Into<String>) -> Self {
102 Self::AlreadyExists { path: path.into() }
103 }
104
105 pub fn invalid_file_name(name: impl Into<String>, reason: impl Into<String>) -> Self {
106 Self::InvalidFileName {
107 name: name.into(),
108 reason: reason.into(),
109 }
110 }
111
112 #[cfg(windows)]
113 pub fn platform_error(message: impl Into<String>, code: Option<u32>) -> Self {
114 Self::PlatformError {
115 message: message.into(),
116 code,
117 }
118 }
119
120 #[cfg(not(windows))]
121 pub fn platform_error(message: impl Into<String>) -> Self {
122 Self::PlatformError {
123 message: message.into(),
124 }
125 }
126
127 pub fn access_denied(path: impl Into<String>, tried_strategies: Vec<String>) -> Self {
128 Self::AccessDenied {
129 path: path.into(),
130 tried_strategies,
131 }
132 }
133}