use cfg_if::cfg_if;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Error)]
pub enum Error {
#[error("Wiggle GuestError: {0}")]
Guest(#[from] wiggle::GuestError),
#[error("TryFromIntError: {0}")]
TryFromInt(#[from] std::num::TryFromIntError),
#[error("Utf8Error: {0}")]
Utf8(#[from] std::str::Utf8Error),
#[error("GetRandom: {0}")]
GetRandom(#[from] getrandom::Error),
#[error("Unexpected IoError: {0}")]
UnexpectedIo(#[source] std::io::Error),
#[error("TooBig: Argument list too long")]
TooBig,
#[error("Acces: Permission denied")]
Acces,
#[error("Badf: Bad file descriptor")]
Badf,
#[error("Busy: Device or resource busy")]
Busy,
#[error("Exist: File exists")]
Exist,
#[error("Fault: Bad address")]
Fault,
#[error("Fbig: File too large")]
Fbig,
#[error("Ilseq: Illegal byte sequence")]
Ilseq,
#[error("Inval: Invalid argument")]
Inval,
#[error("Io: I/o error")]
Io,
#[error("Isdir: Is a directory")]
Isdir,
#[error("Loop: Too many levels of symbolic links")]
Loop,
#[error("Mfile: File descriptor value too large")]
Mfile,
#[error("Mlink: Too many links")]
Mlink,
#[error("Nametoolong: Filename too long")]
Nametoolong,
#[error("Nfile: Too many files open in system")]
Nfile,
#[error("Noent: No such file or directory")]
Noent,
#[error("Nomem: Not enough space")]
Nomem,
#[error("Nospc: No space left on device")]
Nospc,
#[error("Notdir: Not a directory or a symbolic link to a directory")]
Notdir,
#[error("Notempty: Directory not empty")]
Notempty,
#[error("Notsup: Not supported, or operation not supported on socket")]
Notsup,
#[error("Overflow: Value too large to be stored in data type")]
Overflow,
#[error("Pipe: Broken pipe")]
Pipe,
#[error("Perm: Operation not permitted")]
Perm,
#[error("Spipe: Invalid seek")]
Spipe,
#[error("Notcapable: cabailities insufficient")]
Notcapable,
}
impl From<std::convert::Infallible> for Error {
fn from(_err: std::convert::Infallible) -> Self {
unreachable!("should be impossible: From<Infallible>")
}
}
cfg_if! {
if #[cfg(windows)] {
use winapi::shared::winerror;
use std::io;
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
match err.raw_os_error() {
Some(code) => match code as u32 {
winerror::ERROR_BAD_ENVIRONMENT => Self::TooBig,
winerror::ERROR_FILE_NOT_FOUND => Self::Noent,
winerror::ERROR_PATH_NOT_FOUND => Self::Noent,
winerror::ERROR_TOO_MANY_OPEN_FILES => Self::Nfile,
winerror::ERROR_ACCESS_DENIED => Self::Acces,
winerror::ERROR_SHARING_VIOLATION => Self::Acces,
winerror::ERROR_PRIVILEGE_NOT_HELD => Self::Notcapable,
winerror::ERROR_INVALID_HANDLE => Self::Badf,
winerror::ERROR_INVALID_NAME => Self::Noent,
winerror::ERROR_NOT_ENOUGH_MEMORY => Self::Nomem,
winerror::ERROR_OUTOFMEMORY => Self::Nomem,
winerror::ERROR_DIR_NOT_EMPTY => Self::Notempty,
winerror::ERROR_NOT_READY => Self::Busy,
winerror::ERROR_BUSY => Self::Busy,
winerror::ERROR_NOT_SUPPORTED => Self::Notsup,
winerror::ERROR_FILE_EXISTS => Self::Exist,
winerror::ERROR_BROKEN_PIPE => Self::Pipe,
winerror::ERROR_BUFFER_OVERFLOW => Self::Nametoolong,
winerror::ERROR_NOT_A_REPARSE_POINT => Self::Inval,
winerror::ERROR_NEGATIVE_SEEK => Self::Inval,
winerror::ERROR_DIRECTORY => Self::Notdir,
winerror::ERROR_ALREADY_EXISTS => Self::Exist,
_ => Self::UnexpectedIo(err),
},
None => Self::UnexpectedIo(err),
}
}
}
} else {
use std::io;
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
match err.raw_os_error() {
Some(code) => match code {
libc::EPIPE => Self::Pipe,
libc::EPERM => Self::Perm,
libc::ENOENT => Self::Noent,
libc::ENOMEM => Self::Nomem,
libc::E2BIG => Self::TooBig,
libc::EIO => Self::Io,
libc::EBADF => Self::Badf,
libc::EBUSY => Self::Busy,
libc::EACCES => Self::Acces,
libc::EFAULT => Self::Fault,
libc::ENOTDIR => Self::Notdir,
libc::EISDIR => Self::Isdir,
libc::EINVAL => Self::Inval,
libc::EEXIST => Self::Exist,
libc::EFBIG => Self::Fbig,
libc::ENOSPC => Self::Nospc,
libc::ESPIPE => Self::Spipe,
libc::EMFILE => Self::Mfile,
libc::EMLINK => Self::Mlink,
libc::ENAMETOOLONG => Self::Nametoolong,
libc::ENFILE => Self::Nfile,
libc::ENOTEMPTY => Self::Notempty,
libc::ELOOP => Self::Loop,
libc::EOVERFLOW => Self::Overflow,
libc::EILSEQ => Self::Ilseq,
libc::ENOTSUP => Self::Notsup,
_ => Self::UnexpectedIo(err),
},
None => {
Self::UnexpectedIo(err)
}
}
}
}
}
}