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 + core::error::Error> 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 DeleteNonEmptyDir => 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(x) => Self::BadBlockSize(x),
142 InvalidOffset => Self::InvalidOffset,
143 DiskFull => Self::DiskFull,
144 DirAlreadyExists => Self::DirAlreadyExists,
145 LockError => Self::Other,
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
267#[derive(Debug)]
268pub enum NetworkError {
269 NotInitialized,
270 AlreadyInitialized,
271 UnknownPeer,
272 CannotBind,
273 PeerListFull,
274 RecvError,
275 SendError,
276 NetThreadDeallocated,
277 OutMessageTooBig,
278 UnexpectedResp,
279 Decode(postcard::Error),
280 Uart(&'static str),
281 Error(&'static str),
282 OwnedError(alloc::string::String),
283 Other(u32),
284}
285
286impl core::error::Error for NetworkError {}
287
288impl From<postcard::Error> for NetworkError {
289 fn from(v: postcard::Error) -> Self {
290 Self::Decode(v)
291 }
292}
293
294#[cfg(target_os = "none")]
309impl From<esp_hal::uart::RxError> for NetworkError {
310 fn from(value: esp_hal::uart::RxError) -> Self {
311 let msg = match value {
312 esp_hal::uart::RxError::FifoOverflowed => "RX FIFO overflowed",
313 esp_hal::uart::RxError::GlitchOccurred => "glitch on RX line",
314 esp_hal::uart::RxError::FrameFormatViolated => "framing error on RX line",
315 esp_hal::uart::RxError::ParityMismatch => "parity error on RX line",
316 _ => "unknown RX error",
317 };
318 Self::Uart(msg)
319 }
320}
321
322#[cfg(target_os = "none")]
323impl From<esp_hal::uart::TxError> for NetworkError {
324 fn from(_: esp_hal::uart::TxError) -> Self {
325 Self::Uart("unknown TX error")
326 }
327}
328
329#[cfg(target_os = "none")]
330impl From<esp_hal::uart::IoError> for NetworkError {
331 fn from(err: esp_hal::uart::IoError) -> Self {
332 match err {
333 esp_hal::uart::IoError::Tx(err) => err.into(),
334 esp_hal::uart::IoError::Rx(err) => err.into(),
335 _ => Self::Uart("unknown IO error"),
336 }
337 }
338}
339
340#[cfg(target_os = "none")]
341impl From<embedded_io::ReadExactError<esp_hal::uart::IoError>> for NetworkError {
342 fn from(err: embedded_io::ReadExactError<esp_hal::uart::IoError>) -> Self {
343 match err {
344 embedded_io::ReadExactError::UnexpectedEof => Self::Uart("unexpected EoF"),
345 embedded_io::ReadExactError::Other(err) => err.into(),
346 }
347 }
348}
349
350impl fmt::Display for NetworkError {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 use NetworkError::*;
353 match self {
354 NotInitialized => write!(f, "cannot send messages with Wi-Fi turned off"),
355 AlreadyInitialized => write!(f, "tried to initialize networking twice"),
356 UnknownPeer => write!(f, "cannot send messages to disconnected device"),
357 CannotBind => write!(f, "cannot find free address for networking"),
358 PeerListFull => write!(f, "cannot connect more devices"),
359 RecvError => write!(f, "cannot fetch network message"),
360 SendError => write!(f, "cannot send network message"),
361 NetThreadDeallocated => write!(f, "thread handling networking is already deallocated"),
362 OutMessageTooBig => write!(f, "outgoing message is too big"),
363 UnexpectedResp => write!(f, "unexpected response"),
364 Decode(err) => write!(f, "decode message: {err}"),
365 Uart(err) => write!(f, "SPI error: {err}"),
366 Error(err) => write!(f, "network error: {err}"),
367 OwnedError(err) => write!(f, "network error: {err}"),
368 Other(n) => write!(f, "network error #{n}"),
369 }
370 }
371}