diff --git a/embedded-io/src/adapters.rs b/embedded-io/src/adapters.rs index 729f8dc0d..d64c92e4b 100644 --- a/embedded-io/src/adapters.rs +++ b/embedded-io/src/adapters.rs @@ -126,15 +126,51 @@ impl std::io::Seek for ToStd { } } -fn to_std_error(err: T) -> std::io::Error { - let kind = std::io::ErrorKind::Other; +fn to_std_error(err: T) -> std::io::Error { + let kind = match err.kind() { + crate::ErrorKind::NotFound => std::io::ErrorKind::NotFound, + crate::ErrorKind::PermissionDenied => std::io::ErrorKind::PermissionDenied, + crate::ErrorKind::ConnectionRefused => std::io::ErrorKind::ConnectionRefused, + crate::ErrorKind::ConnectionReset => std::io::ErrorKind::ConnectionReset, + crate::ErrorKind::ConnectionAborted => std::io::ErrorKind::ConnectionAborted, + crate::ErrorKind::NotConnected => std::io::ErrorKind::NotConnected, + crate::ErrorKind::AddrInUse => std::io::ErrorKind::AddrInUse, + crate::ErrorKind::AddrNotAvailable => std::io::ErrorKind::AddrNotAvailable, + crate::ErrorKind::BrokenPipe => std::io::ErrorKind::BrokenPipe, + crate::ErrorKind::AlreadyExists => std::io::ErrorKind::AlreadyExists, + crate::ErrorKind::InvalidInput => std::io::ErrorKind::InvalidInput, + crate::ErrorKind::InvalidData => std::io::ErrorKind::InvalidData, + crate::ErrorKind::TimedOut => std::io::ErrorKind::TimedOut, + crate::ErrorKind::Interrupted => std::io::ErrorKind::Interrupted, + crate::ErrorKind::Unsupported => std::io::ErrorKind::Unsupported, + crate::ErrorKind::OutOfMemory => std::io::ErrorKind::OutOfMemory, + _ => std::io::ErrorKind::Other, + }; std::io::Error::new(kind, format!("{:?}", err)) } #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl crate::Error for std::io::Error { fn kind(&self) -> crate::ErrorKind { - crate::ErrorKind::Other + match self.kind() { + std::io::ErrorKind::NotFound => crate::ErrorKind::NotFound, + std::io::ErrorKind::PermissionDenied => crate::ErrorKind::PermissionDenied, + std::io::ErrorKind::ConnectionRefused => crate::ErrorKind::ConnectionRefused, + std::io::ErrorKind::ConnectionReset => crate::ErrorKind::ConnectionReset, + std::io::ErrorKind::ConnectionAborted => crate::ErrorKind::ConnectionAborted, + std::io::ErrorKind::NotConnected => crate::ErrorKind::NotConnected, + std::io::ErrorKind::AddrInUse => crate::ErrorKind::AddrInUse, + std::io::ErrorKind::AddrNotAvailable => crate::ErrorKind::AddrNotAvailable, + std::io::ErrorKind::BrokenPipe => crate::ErrorKind::BrokenPipe, + std::io::ErrorKind::AlreadyExists => crate::ErrorKind::AlreadyExists, + std::io::ErrorKind::InvalidInput => crate::ErrorKind::InvalidInput, + std::io::ErrorKind::InvalidData => crate::ErrorKind::InvalidData, + std::io::ErrorKind::TimedOut => crate::ErrorKind::TimedOut, + std::io::ErrorKind::Interrupted => crate::ErrorKind::Interrupted, + std::io::ErrorKind::Unsupported => crate::ErrorKind::Unsupported, + std::io::ErrorKind::OutOfMemory => crate::ErrorKind::OutOfMemory, + _ => crate::ErrorKind::Other, + } } } diff --git a/embedded-io/src/lib.rs b/embedded-io/src/lib.rs index b71c43f5a..1a8487889 100644 --- a/embedded-io/src/lib.rs +++ b/embedded-io/src/lib.rs @@ -29,9 +29,67 @@ pub enum SeekFrom { #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[non_exhaustive] /// Possible kinds of errors. +/// +/// This list is intended to grow over time and it is not recommended to +/// exhaustively match against it. In application code, use `match` for the `ErrorKind` +/// values you are expecting; use `_` to match "all other errors". +/// +/// This is the `embedded-io` equivalent of [`std::io::ErrorKind`], except with the following changes: +/// +/// - `WouldBlock` is removed, since `embedded-io` traits are always blocking. See the [crate-level documentation](crate) for details. +/// - `WriteZero` is removed, since it is a separate variant in [`WriteAllError`] and [`WriteFmtError`]. pub enum ErrorKind { /// Unspecified error kind. Other, + + /// An entity was not found, often a file. + NotFound, + /// The operation lacked the necessary privileges to complete. + PermissionDenied, + /// The connection was refused by the remote server. + ConnectionRefused, + /// The connection was reset by the remote server. + ConnectionReset, + /// The connection was aborted (terminated) by the remote server. + ConnectionAborted, + /// The network operation failed because it was not connected yet. + NotConnected, + /// A socket address could not be bound because the address is already in + /// use elsewhere. + AddrInUse, + /// A nonexistent interface was requested or the requested address was not + /// local. + AddrNotAvailable, + /// The operation failed because a pipe was closed. + BrokenPipe, + /// An entity already exists, often a file. + AlreadyExists, + /// A parameter was incorrect. + InvalidInput, + /// Data not valid for the operation were encountered. + /// + /// Unlike [`InvalidInput`], this typically means that the operation + /// parameters were valid, however the error was caused by malformed + /// input data. + /// + /// For example, a function that reads a file into a string will error with + /// `InvalidData` if the file's contents are not valid UTF-8. + /// + /// [`InvalidInput`]: ErrorKind::InvalidInput + InvalidData, + /// The I/O operation's timeout expired, causing it to be canceled. + TimedOut, + /// This operation was interrupted. + /// + /// Interrupted operations can typically be retried. + Interrupted, + /// This operation is unsupported on this platform. + /// + /// This means that the operation can never succeed. + Unsupported, + /// An operation could not be completed, because it failed + /// to allocate enough memory. + OutOfMemory, } /// Error trait.