#[cfg(feature = "std")]
use crate::kind::FromIoKind;
use crate::kind::{ErrorKind, FromRawOsError};
pub trait FromOsError: ErrorKind {
fn from_os_error(err: OsError) -> Self;
}
impl<E: FromOsError> FromRawOsError for E {
fn from_raw_os_error(raw: crate::RawOsError) -> Self {
Self::from_os_error(OsError::from_raw_os_error(raw))
}
}
#[cfg(feature = "std")]
impl<E: FromOsError> FromIoKind for E {
fn from_io_error_kind(kind: std::io::ErrorKind) -> Self {
Self::from_os_error(OsError::from_io_error_kind(kind))
}
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
#[non_exhaustive]
pub enum OsError {
#[doc(hidden)]
__Uncategorized,
Other,
PermissionDenied,
NotFound,
NoSuchProcess,
Interrupted,
InputOutputError,
TooBig,
ExecFormatError,
InvalidHandle,
NoChild,
WouldBlock,
NoMemory,
InvalidMemory,
WrongDeviceKind,
Busy,
ObjectExists,
CrossDevice,
NoSuchDevice,
NotADirectory,
IsADirectory,
InvalidArgument,
GlobalHandleExhaustion,
HandleExhaustion,
Ioctl,
TextFileBusy,
NoSpaceLeft,
InvalidSeek,
ReadOnlyFilesystem,
TooManyLinks,
SymbolicLinkChain,
BrokenPipe,
DomainError,
RangeError,
Deadlock,
ResourceExhaustion,
UnsupportedSystemOp,
ConnectionRefused,
ConnectionReset,
InvalidFilename,
InProgress,
QuotaExceeded,
HostUnreachable,
NetworkUnreachable,
ConnectionAborted,
NotConnected,
AddrInUse,
AddrNotAvailable,
NetworkDown,
InvalidData,
TimedOut,
StaleNetworkFileHandle,
DirectoryNotEmpty,
UnexpectedEof,
WriteZero,
AlreadyInProgress,
}
impl core::fmt::Display for OsError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
OsError::__Uncategorized => f.write_str("Uncategorized Error"),
OsError::Other => f.write_str("Other Error"),
OsError::PermissionDenied => f.write_str("Permission Denied"),
OsError::NotFound => f.write_str("Object not found"),
OsError::NoSuchProcess => f.write_str("No such process"),
OsError::Interrupted => f.write_str("Interrupted"),
OsError::InputOutputError => f.write_str("I/O Error"),
OsError::TooBig => f.write_str("Object too big"),
OsError::ExecFormatError => f.write_str("Executable format error"),
OsError::InvalidHandle => f.write_str("Invalid Handle/Descriptor"),
OsError::NoChild => f.write_str("No Child Found"),
OsError::WouldBlock => f.write_str("Operation would block"),
OsError::NoMemory => f.write_str("Out of memory"),
OsError::InvalidMemory => f.write_str("Invalid Memory"),
OsError::WrongDeviceKind => f.write_str("Wrong Device Kind"),
OsError::Busy => f.write_str("Device or Object Busy"),
OsError::ObjectExists => f.write_str("Object Exists"),
OsError::CrossDevice => f.write_str("Operation crosses devices"),
OsError::NoSuchDevice => f.write_str("No such device"),
OsError::NotADirectory => f.write_str("Not a Directory"),
OsError::IsADirectory => f.write_str("Is a Directory"),
OsError::InvalidArgument => f.write_str("Invalid Argument"),
OsError::GlobalHandleExhaustion => f.write_str("Too many Global Handles/Descriptors"),
OsError::HandleExhaustion => f.write_str("Too many Local Handles/Descriptors"),
OsError::Ioctl => f.write_str("Invalid Ioctl for device"),
OsError::TextFileBusy => f.write_str("Executable File Busy"),
OsError::NoSpaceLeft => f.write_str("No Space Left on Device"),
OsError::InvalidSeek => f.write_str("Invalid Seek on Non-seekable Handle"),
OsError::ReadOnlyFilesystem => f.write_str("Read-only Filesystem"),
OsError::SymbolicLinkChain => f.write_str("Symbolic Link Loop or Chain"),
OsError::BrokenPipe => f.write_str("Broken Pipe"),
OsError::UnsupportedSystemOp => f.write_str("Unsupported System Call"),
OsError::TooManyLinks => f.write_str("Too many links"),
OsError::DomainError => f.write_str("Domain Error"),
OsError::RangeError => f.write_str("Output out of range"),
OsError::Deadlock => f.write_str("Deadlock Detected"),
OsError::ResourceExhaustion => f.write_str("Other Resource Exhaustion"),
OsError::ConnectionRefused => f.write_str("Connection Refused"),
OsError::ConnectionReset => f.write_str("Connection Reset"),
OsError::InvalidFilename => f.write_str("Invalid File Name"),
OsError::InProgress => f.write_str("Operation In Progress"),
OsError::QuotaExceeded => f.write_str("Quota/Resource Limit Exceeded"),
OsError::HostUnreachable => f.write_str("Destination Host Unreachable"),
OsError::NetworkUnreachable => f.write_str("Destination Network Unreachable"),
OsError::ConnectionAborted => f.write_str("Connection Aborted"),
OsError::NotConnected => f.write_str("Not Connected"),
OsError::AddrInUse => f.write_str("Address In Use"),
OsError::AddrNotAvailable => f.write_str("Address Not Available"),
OsError::NetworkDown => f.write_str("Network Down"),
OsError::InvalidData => f.write_str("Invalid Data"),
OsError::TimedOut => f.write_str("Operation Timed Out"),
OsError::StaleNetworkFileHandle => f.write_str("Stale File Handle"),
OsError::DirectoryNotEmpty => f.write_str("Directory Not Empty"),
OsError::UnexpectedEof => f.write_str("Unexpected Eof"),
OsError::WriteZero => f.write_str("Write returned 0"),
OsError::AlreadyInProgress => f.write_str(" Operation Already Pending"),
}
}
}
impl ErrorKind for OsError {
const OTHER: Self = OsError::Other;
fn uncategorized() -> Self {
Self::__Uncategorized
}
}
impl FromRawOsError for OsError {
fn from_raw_os_error(raw: crate::RawOsError) -> Self {
os_error(raw)
}
}
#[cfg(feature = "std")]
impl FromIoKind for OsError {
fn from_io_error_kind(kind: std::io::ErrorKind) -> Self {
match kind {
std::io::ErrorKind::NotFound => OsError::NotFound,
std::io::ErrorKind::PermissionDenied => OsError::PermissionDenied,
std::io::ErrorKind::ConnectionRefused => OsError::ConnectionRefused,
std::io::ErrorKind::ConnectionReset => OsError::ConnectionReset,
std::io::ErrorKind::BrokenPipe => OsError::BrokenPipe,
std::io::ErrorKind::AlreadyExists => OsError::ObjectExists,
std::io::ErrorKind::WouldBlock => OsError::WouldBlock,
std::io::ErrorKind::NotADirectory => OsError::NotADirectory,
std::io::ErrorKind::IsADirectory => OsError::IsADirectory,
std::io::ErrorKind::ReadOnlyFilesystem => OsError::ReadOnlyFilesystem,
std::io::ErrorKind::InvalidInput => OsError::InvalidArgument,
std::io::ErrorKind::StorageFull => OsError::NoSpaceLeft,
std::io::ErrorKind::NotSeekable => OsError::InvalidSeek,
std::io::ErrorKind::FileTooLarge => OsError::TooBig,
std::io::ErrorKind::ResourceBusy => OsError::Busy,
std::io::ErrorKind::ExecutableFileBusy => OsError::TextFileBusy,
std::io::ErrorKind::Deadlock => OsError::Deadlock,
std::io::ErrorKind::CrossesDevices => OsError::CrossDevice,
std::io::ErrorKind::TooManyLinks => OsError::TooManyLinks,
std::io::ErrorKind::ArgumentListTooLong => OsError::TooBig,
std::io::ErrorKind::Interrupted => OsError::Interrupted,
std::io::ErrorKind::Unsupported => OsError::UnsupportedSystemOp,
std::io::ErrorKind::OutOfMemory => OsError::NoMemory,
#[cfg(feature = "nightly-io_error_more")]
std::io::ErrorKind::FilesystemLoop => OsError::SymbolicLinkChain,
#[cfg(feature = "nightly-io_error_more")]
std::io::ErrorKind::InProgress => OsError::InProgress,
std::io::ErrorKind::QuotaExceeded => OsError::QuotaExceeded,
std::io::ErrorKind::InvalidFilename => OsError::InvalidFilename,
std::io::ErrorKind::UnexpectedEof => OsError::UnexpectedEof,
std::io::ErrorKind::HostUnreachable => OsError::HostUnreachable,
std::io::ErrorKind::NetworkUnreachable => OsError::NetworkUnreachable,
std::io::ErrorKind::ConnectionAborted => OsError::ConnectionAborted,
std::io::ErrorKind::NotConnected => OsError::NotConnected,
std::io::ErrorKind::AddrInUse => OsError::AddrInUse,
std::io::ErrorKind::AddrNotAvailable => OsError::AddrNotAvailable,
std::io::ErrorKind::NetworkDown => OsError::NetworkDown,
std::io::ErrorKind::InvalidData => OsError::InvalidData,
std::io::ErrorKind::TimedOut => OsError::TimedOut,
std::io::ErrorKind::WriteZero => OsError::WriteZero,
std::io::ErrorKind::StaleNetworkFileHandle => OsError::StaleNetworkFileHandle,
std::io::ErrorKind::DirectoryNotEmpty => OsError::DirectoryNotEmpty,
std::io::ErrorKind::Other => OsError::Other,
_ => OsError::__Uncategorized,
}
}
}
cfg_select! {
target_os = "linux" => {
fn os_error(error: crate::RawOsError) -> OsError {
use linux_errno::*;
match u16::try_from(error).ok().and_then(Error::new) {
Some(err) => {
match err {
EPERM | EACCES => OsError::PermissionDenied,
ENOENT => OsError::NotFound,
ESRCH => OsError::NoSuchProcess,
E2BIG | EFBIG | ENAMETOOLONG => OsError::TooBig,
EBADF => OsError::InvalidHandle,
ECHILD => OsError::NoChild,
EAGAIN => OsError::WouldBlock,
ENOMEM => OsError::NoMemory,
EFAULT => OsError::InvalidMemory,
ENOTBLK => OsError::WrongDeviceKind,
EBUSY => OsError::Busy,
EXDEV => OsError::CrossDevice,
ENODEV | ENXIO => OsError::NoSuchDevice,
ENOTDIR => OsError::NotADirectory,
EISDIR => OsError::IsADirectory,
EINVAL => OsError::InvalidArgument,
ENFILE => OsError::GlobalHandleExhaustion,
EMFILE => OsError::HandleExhaustion,
ENOTTY => OsError::Ioctl,
ETXTBSY => OsError::TextFileBusy,
ENOSPC => OsError::NoSpaceLeft,
ESPIPE => OsError::InvalidSeek,
EMLINK => OsError::TooManyLinks,
EPIPE => OsError::BrokenPipe,
EDOM => OsError::DomainError,
ERANGE => OsError::RangeError,
EDEADLK => OsError::Deadlock,
ENOLCK => OsError::ResourceExhaustion,
ENOSYS => OsError::UnsupportedSystemOp,
EINPROGRESS => OsError::InProgress,
EALREADY => OsError::AlreadyInProgress,
ETIME => OsError::TimedOut,
_ => OsError::__Uncategorized,
}
}
None => OsError::__Uncategorized
}
}
}
target_os = "lilium" => {
fn os_error(error: crate::RawOsError) -> OsError {
todo!()
}
}
target_os = "windows" => {
fn os_error(error: crate::RawOsError) -> OsError {
todo!()
}
}
_ => {
fn os_error(error: crate::RawOsError) -> OsError {
}
}
}