1use core::fmt;
2
3#[derive(Debug)]
4pub enum FSError {
5 DeviceError(alloc::string::String),
7 FormatError(&'static str),
9 NoSuchVolume,
11 #[cfg(target_os = "none")]
13 FilenameError(embedded_sdmmc::FilenameError),
14 TooManyOpenVolumes,
16 TooManyOpenDirs,
18 TooManyOpenFiles,
20 BadHandle,
22 NotFound,
24 FileAlreadyOpen,
26 DirAlreadyOpen,
28 OpenedDirAsFile,
30 OpenedFileAsDir,
32 DeleteDirAsFile,
34 VolumeStillInUse,
36 VolumeAlreadyOpen,
38 Unsupported,
40 EndOfFile,
42 BadCluster,
44 ConversionError,
46 NotEnoughSpace,
48 AllocationError,
50 UnterminatedFatChain,
52 ReadOnly,
54 FileAlreadyExists,
56 BadBlockSize(u16),
58 InvalidOffset,
60 DiskFull,
62 DirAlreadyExists,
64 Deadlock,
66
67 PermissionDenied,
69 ConnectionRefused,
71 ConnectionReset,
73 ConnectionAborted,
75 NotConnected,
77 AddrInUse,
80 AddrNotAvailable,
83 BrokenPipe,
85 InvalidInput,
87 InvalidData,
98 TimedOut,
100 Interrupted,
104 WriteZero,
106
107 Other,
109}
110
111#[cfg(target_os = "none")]
112impl<T: fmt::Debug> From<embedded_sdmmc::Error<T>> for FSError {
113 fn from(value: embedded_sdmmc::Error<T>) -> Self {
114 use embedded_sdmmc::Error::*;
115 match value {
116 DeviceError(e) => Self::DeviceError(alloc::format!("{e:?}")),
117 FormatError(e) => Self::FormatError(e),
118 NoSuchVolume => Self::NoSuchVolume,
119 FilenameError(e) => Self::FilenameError(e),
120 TooManyOpenVolumes => Self::TooManyOpenVolumes,
121 TooManyOpenDirs => Self::TooManyOpenDirs,
122 TooManyOpenFiles => Self::TooManyOpenFiles,
123 BadHandle => Self::BadHandle,
124 NotFound => Self::NotFound,
125 FileAlreadyOpen => Self::FileAlreadyOpen,
126 DirAlreadyOpen => Self::DirAlreadyOpen,
127 OpenedDirAsFile => Self::OpenedDirAsFile,
128 OpenedFileAsDir => Self::OpenedFileAsDir,
129 DeleteDirAsFile => Self::DeleteDirAsFile,
130 VolumeStillInUse => Self::VolumeStillInUse,
131 VolumeAlreadyOpen => Self::VolumeAlreadyOpen,
132 Unsupported => Self::Unsupported,
133 EndOfFile => Self::EndOfFile,
134 BadCluster => Self::BadCluster,
135 ConversionError => Self::ConversionError,
136 NotEnoughSpace => Self::NotEnoughSpace,
137 AllocationError => Self::AllocationError,
138 UnterminatedFatChain => Self::UnterminatedFatChain,
139 ReadOnly => Self::ReadOnly,
140 FileAlreadyExists => Self::FileAlreadyExists,
141 BadBlockSize(size) => Self::BadBlockSize(size),
142 InvalidOffset => Self::InvalidOffset,
143 DiskFull => Self::DiskFull,
144 DirAlreadyExists => Self::DirAlreadyExists,
145 LockError => Self::Deadlock,
146 }
147 }
148}
149
150#[cfg(not(target_os = "none"))]
151impl From<std::io::Error> for FSError {
152 fn from(value: std::io::Error) -> Self {
153 value.kind().into()
154 }
155}
156
157#[cfg(not(target_os = "none"))]
158impl From<std::io::ErrorKind> for FSError {
159 fn from(value: std::io::ErrorKind) -> Self {
160 use std::io::ErrorKind::*;
161 match value {
162 NotFound => Self::NotFound,
163 PermissionDenied => Self::PermissionDenied,
164 ConnectionRefused => Self::ConnectionRefused,
165 ConnectionReset => Self::ConnectionReset,
166 ConnectionAborted => Self::ConnectionAborted,
167 NotConnected => Self::NotConnected,
168 AddrInUse => Self::AddrInUse,
169 AddrNotAvailable => Self::AddrNotAvailable,
170 BrokenPipe => Self::BrokenPipe,
171 AlreadyExists => Self::FileAlreadyExists,
172 WouldBlock => Self::Other,
173 InvalidInput => Self::InvalidInput,
174 InvalidData => Self::InvalidData,
175 TimedOut => Self::TimedOut,
176 WriteZero => Self::WriteZero,
177 Interrupted => Self::Interrupted,
178 Unsupported => Self::Unsupported,
179 UnexpectedEof => Self::EndOfFile,
180 OutOfMemory => Self::DiskFull,
181 Other => Self::Other,
182 _ => Self::Other,
183 }
184 }
185}
186
187impl From<embedded_io::ErrorKind> for FSError {
188 fn from(value: embedded_io::ErrorKind) -> Self {
189 use embedded_io::ErrorKind::*;
190 match value {
191 Other => Self::Other,
192 NotFound => Self::NotFound,
193 PermissionDenied => Self::PermissionDenied,
194 ConnectionRefused => Self::ConnectionRefused,
195 ConnectionReset => Self::ConnectionReset,
196 ConnectionAborted => Self::ConnectionAborted,
197 NotConnected => Self::NotConnected,
198 AddrInUse => Self::AddrInUse,
199 AddrNotAvailable => Self::AddrNotAvailable,
200 BrokenPipe => Self::BrokenPipe,
201 AlreadyExists => Self::FileAlreadyExists,
202 InvalidInput => Self::InvalidInput,
203 InvalidData => Self::InvalidData,
204 TimedOut => Self::TimedOut,
205 Interrupted => Self::Interrupted,
206 Unsupported => Self::Unsupported,
207 OutOfMemory => Self::DiskFull,
208 WriteZero => Self::WriteZero,
209 _ => Self::Other,
210 }
211 }
212}
213
214impl fmt::Display for FSError {
215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216 use FSError::*;
217 match self {
218 DeviceError(e) => write!(f, "device error: {e}"),
219 FormatError(e) => write!(f, "format error: {e}"),
220 NoSuchVolume => write!(f, "no such volume"),
221 #[cfg(target_os = "none")]
222 FilenameError(e) => write!(f, "filename error: {e:?}"),
223 TooManyOpenVolumes => write!(f, "too many open volumes"),
224 TooManyOpenDirs => write!(f, "too many open dirs"),
225 TooManyOpenFiles => write!(f, "too many open files"),
226 BadHandle => write!(f, "bad handle"),
227 NotFound => write!(f, "not found"),
228 FileAlreadyOpen => write!(f, "file already open"),
229 DirAlreadyOpen => write!(f, "dir already open"),
230 OpenedDirAsFile => write!(f, "opened dir as file"),
231 OpenedFileAsDir => write!(f, "opened file as dir"),
232 DeleteDirAsFile => write!(f, "delete dir as file"),
233 VolumeStillInUse => write!(f, "volume still in use"),
234 VolumeAlreadyOpen => write!(f, "volume already open"),
235 Unsupported => write!(f, "unsupported"),
236 EndOfFile => write!(f, "end of file"),
237 BadCluster => write!(f, "bad cluster"),
238 ConversionError => write!(f, "conversion error"),
239 NotEnoughSpace => write!(f, "not enough space"),
240 AllocationError => write!(f, "allocation error"),
241 UnterminatedFatChain => write!(f, "unterminated fat chain"),
242 ReadOnly => write!(f, "read only"),
243 FileAlreadyExists => write!(f, "file already exists"),
244 BadBlockSize(_) => write!(f, "bad block size"),
245 InvalidOffset => write!(f, "invalid offset"),
246 DiskFull => write!(f, "disk full"),
247 DirAlreadyExists => write!(f, "dir already exists"),
248 PermissionDenied => write!(f, "permission denied"),
249 ConnectionRefused => write!(f, "connection refused"),
250 ConnectionReset => write!(f, "connection reset"),
251 ConnectionAborted => write!(f, "connection aborted"),
252 NotConnected => write!(f, "not connected"),
253 AddrInUse => write!(f, "addr in use"),
254 AddrNotAvailable => write!(f, "addr not available"),
255 BrokenPipe => write!(f, "broken pipe"),
256 InvalidInput => write!(f, "invalid input"),
257 InvalidData => write!(f, "invalid data"),
258 TimedOut => write!(f, "timed out"),
259 Interrupted => write!(f, "interrupted"),
260 WriteZero => write!(f, "write zero"),
261 Deadlock => write!(f, "deadlock"),
262 Other => write!(f, "other"),
263 }
264 }
265}
266
267pub enum NetworkError {
268 NotInitialized,
269 AlreadyInitialized,
270 UnknownPeer,
271 CannotBind,
272 PeerListFull,
273 RecvError,
274 SendError,
275 NetThreadDeallocated,
276 OutMessageTooBig,
277 UnexpectedResp,
278 Decode(postcard::Error),
279 Uart(&'static str),
280 Error(&'static str),
281 OwnedError(alloc::string::String),
282 Other(u32),
283}
284
285impl From<postcard::Error> for NetworkError {
286 fn from(v: postcard::Error) -> Self {
287 Self::Decode(v)
288 }
289}
290
291#[cfg(target_os = "none")]
306impl From<esp_hal::uart::RxError> for NetworkError {
307 fn from(value: esp_hal::uart::RxError) -> Self {
308 let msg = match value {
309 esp_hal::uart::RxError::FifoOverflowed => "RX FIFO overflowed",
310 esp_hal::uart::RxError::GlitchOccurred => "glitch on RX line",
311 esp_hal::uart::RxError::FrameFormatViolated => "framing error on RX line",
312 esp_hal::uart::RxError::ParityMismatch => "parity error on RX line",
313 _ => "unknown RX error",
314 };
315 Self::Uart(msg)
316 }
317}
318
319#[cfg(target_os = "none")]
320impl From<esp_hal::uart::TxError> for NetworkError {
321 fn from(_: esp_hal::uart::TxError) -> Self {
322 Self::Uart("unknown TX error")
323 }
324}
325
326#[cfg(target_os = "none")]
327impl From<esp_hal::uart::IoError> for NetworkError {
328 fn from(err: esp_hal::uart::IoError) -> Self {
329 match err {
330 esp_hal::uart::IoError::Tx(err) => err.into(),
331 esp_hal::uart::IoError::Rx(err) => err.into(),
332 _ => Self::Uart("unknown IO error"),
333 }
334 }
335}
336
337#[cfg(target_os = "none")]
338impl From<embedded_io::ReadExactError<esp_hal::uart::IoError>> for NetworkError {
339 fn from(err: embedded_io::ReadExactError<esp_hal::uart::IoError>) -> Self {
340 match err {
341 embedded_io::ReadExactError::UnexpectedEof => Self::Uart("unexpected EoF"),
342 embedded_io::ReadExactError::Other(err) => err.into(),
343 }
344 }
345}
346
347impl fmt::Display for NetworkError {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 use NetworkError::*;
350 match self {
351 NotInitialized => write!(f, "cannot send messages with Wi-Fi turned off"),
352 AlreadyInitialized => write!(f, "tried to initialize networking twice"),
353 UnknownPeer => write!(f, "cannot send messages to disconnected device"),
354 CannotBind => write!(f, "cannot find free address for networking"),
355 PeerListFull => write!(f, "cannot connect more devices"),
356 RecvError => write!(f, "cannot fetch network message"),
357 SendError => write!(f, "cannot send network message"),
358 NetThreadDeallocated => write!(f, "thread handling networking is already deallocated"),
359 OutMessageTooBig => write!(f, "outgoing message is too big"),
360 UnexpectedResp => write!(f, "unexpected response"),
361 Decode(err) => write!(f, "decode message: {err}"),
362 Uart(err) => write!(f, "SPI error: {err}"),
363 Error(err) => write!(f, "network error: {err}"),
364 OwnedError(err) => write!(f, "network error: {err}"),
365 Other(n) => write!(f, "network error #{n}"),
366 }
367 }
368}