#[cfg(all(doc, any(feature = "std", feature = "io")))]
use crate::IoSeek;
use crate::{Debug, From, Result, impl_trait};
#[cfg(doc)]
use crate::{IoRead, IoWrite};
#[doc = crate::_tags!(io result)]
pub type IoResult<T> = Result<T, IoError>;
#[doc = crate::_tags!(io error_composite)]
pub struct IoError {
repr: Repr,
}
impl_trait![fmt::Debug for IoError |self, f| Debug::fmt(&self.repr, f)];
impl_trait![fmt::Display+Error for IoError |self, f|
match self.repr {
Repr::Custom(ref c) => Debug::fmt(&c, f),
Repr::Simple(kind) => write!(f, "{}", kind.as_str()),
}
];
#[derive(Clone, Copy, PartialEq)]
enum Repr {
Custom(Custom),
Simple(IoErrorKind),
}
impl_trait![fmt::Debug for Repr |self, f|
match *self {
Repr::Custom(ref c) => Debug::fmt(&c, f),
Repr::Simple(kind) => f.debug_tuple("Kind").field(&kind).finish(),
}
];
#[derive(Clone, Copy, Debug, PartialEq)]
struct Custom {
kind: IoErrorKind,
error: &'static str,
}
#[doc = crate::_tags!(io error_composite)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum IoErrorKind {
NotFound,
PermissionDenied,
ConnectionRefused,
ConnectionReset,
HostUnreachable,
NetworkUnreachable,
ConnectionAborted,
NotConnected,
AddrInUse,
AddrNotAvailable,
NetworkDown,
BrokenPipe,
AlreadyExists,
WouldBlock,
NotADirectory,
IsADirectory,
DirectoryNotEmpty,
ReadOnlyFilesystem,
FilesystemLoop,
StaleNetworkFileHandle,
InvalidInput,
InvalidData,
TimedOut,
WriteZero,
StorageFull,
NotSeekable,
FilesystemQuotaExceeded,
FileTooLarge,
ResourceBusy,
ExecutableFileBusy,
Deadlock,
CrossesDevices,
TooManyLinks,
InvalidFilename,
ArgumentListTooLong,
Interrupted,
Unsupported,
UnexpectedEof,
OutOfMemory,
InProgress,
Other,
}
impl IoErrorKind {
pub(crate) const fn as_str(self) -> &'static str {
use IoErrorKind as E;
match self {
E::AddrInUse => "address in use",
E::AddrNotAvailable => "address not available",
E::AlreadyExists => "entity already exists",
E::ArgumentListTooLong => "argument list too long",
E::BrokenPipe => "broken pipe",
E::ConnectionAborted => "connection aborted",
E::ConnectionRefused => "connection refused",
E::ConnectionReset => "connection reset",
E::CrossesDevices => "cross-device link or rename",
E::Deadlock => "deadlock",
E::DirectoryNotEmpty => "directory not empty",
E::ExecutableFileBusy => "executable file busy",
E::FileTooLarge => "file too large",
E::FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)",
E::FilesystemQuotaExceeded => "filesystem quota exceeded",
E::HostUnreachable => "host unreachable",
E::Interrupted => "operation interrupted",
E::InProgress => "in progress",
E::InvalidData => "invalid data",
E::InvalidFilename => "invalid filename",
E::InvalidInput => "invalid input parameter",
E::IsADirectory => "is a directory",
E::NetworkDown => "network down",
E::NetworkUnreachable => "network unreachable",
E::NotADirectory => "not a directory",
E::NotConnected => "not connected",
E::NotFound => "entity not found",
E::NotSeekable => "seek on unseekable file",
E::Other => "other error",
E::OutOfMemory => "out of memory",
E::PermissionDenied => "permission denied",
E::ReadOnlyFilesystem => "read-only filesystem or storage medium",
E::ResourceBusy => "resource busy",
E::StaleNetworkFileHandle => "stale network file handle",
E::StorageFull => "no storage space",
E::TimedOut => "timed out",
E::TooManyLinks => "too many links",
E::UnexpectedEof => "unexpected end of file",
E::Unsupported => "unsupported",
E::WouldBlock => "operation would block",
E::WriteZero => "write zero",
}
}
}
impl From<IoErrorKind> for IoError {
fn from(kind: IoErrorKind) -> IoError {
IoError { repr: Repr::Simple(kind) }
}
}
impl IoError {
pub const fn new(kind: IoErrorKind, error: &'static str) -> IoError {
IoError { repr: Repr::Custom(Custom { kind, error }) }
}
pub const fn other(msg: &'static str) -> Self {
IoError {
repr: Repr::Custom(Custom { kind: IoErrorKind::Other, error: msg }),
}
}
pub const fn get_ref(&self) -> Option<&&'static str> {
match self.repr {
Repr::Custom(ref c) => Some(&c.error),
Repr::Simple(..) => None,
}
}
pub const fn into_inner(self) -> Option<&'static str> {
match self.repr {
Repr::Custom(c) => Some(c.error),
Repr::Simple(..) => None,
}
}
pub const fn kind(&self) -> IoErrorKind {
match self.repr {
Repr::Custom(ref c) => c.kind,
Repr::Simple(kind) => kind,
}
}
}
const fn _assert_error_is_sync_send() {
const fn _is_sync_send<T: Sync + Send>() {}
_is_sync_send::<IoError>();
}