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