fat32_raw/
error.rs

1//! Error types for the fat32-raw library
2
3use std::fmt;
4use std::io;
5
6/// Result type for fat32-raw operations
7pub type Result<T> = std::result::Result<T, Fat32Error>;
8
9/// Main error type for fat32-raw operations
10#[derive(Debug)]
11pub enum Fat32Error {
12    /// I/O error from underlying file operations
13    Io(io::Error),
14
15    /// Invalid FAT32 structure or parameters
16    InvalidFat32 { message: String },
17
18    /// File or directory not found
19    NotFound { path: String },
20
21    /// File or directory already exists
22    AlreadyExists { path: String },
23
24    /// No free clusters available
25    NoFreeSpace,
26
27    /// Invalid file name
28    InvalidFileName { name: String, reason: String },
29
30    /// Platform-specific error
31    PlatformError {
32        message: String,
33        #[cfg(windows)]
34        code: Option<u32>,
35    },
36
37    /// Access denied (typically on Windows ESP partitions)
38    AccessDenied {
39        path: String,
40        tried_strategies: Vec<String>,
41    },
42
43    /// ESP partition not found
44    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
89// Convenience constructors
90impl 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}