use core::{
fmt::{
self,
Debug,
Display,
Formatter,
},
result::Result as CoreResult,
};
pub const EPERM: u16 = 1;
pub const ENOENT: u16 = 2;
pub const ESRCH: u16 = 3;
pub const EINTR: u16 = 4;
pub const EIO: u16 = 5;
pub const ENXIO: u16 = 6;
pub const E2BIG: u16 = 7;
pub const ENOEXEC: u16 = 8;
pub const EBADF: u16 = 9;
pub const ECHILD: u16 = 10;
pub const EAGAIN: u16 = 11;
pub const ENOMEM: u16 = 12;
pub const EACCES: u16 = 13;
pub const EFAULT: u16 = 14;
pub const ENOTBLK: u16 = 15;
pub const EBUSY: u16 = 16;
pub const EEXIST: u16 = 17;
pub const EXDEV: u16 = 18;
pub const ENODEV: u16 = 19;
pub const ENOTDIR: u16 = 20;
pub const EISDIR: u16 = 21;
pub const EINVAL: u16 = 22;
pub const ENFILE: u16 = 23;
pub const EMFILE: u16 = 24;
pub const ENOTTY: u16 = 25;
pub const ETXTBSY: u16 = 26;
pub const EFBIG: u16 = 27;
pub const ENOSPC: u16 = 28;
pub const ESPIPE: u16 = 29;
pub const EROFS: u16 = 30;
pub const EMLINK: u16 = 31;
pub const EPIPE: u16 = 32;
pub const EDOM: u16 = 33;
pub const ERANGE: u16 = 34;
pub const EDEADLK: u16 = 35;
pub const ENAMETOOLONG: u16 = 36;
pub const ENOLCK: u16 = 37;
pub const ENOSYS: u16 = 38;
pub const ENOTEMPTY: u16 = 39;
pub const ELOOP: u16 = 40;
pub const ENOMSG: u16 = 42;
pub const EIDRM: u16 = 43;
pub const ECHRNG: u16 = 44;
pub const EL2NSYNC: u16 = 45;
pub const EL3HLT: u16 = 46;
pub const EL3RST: u16 = 47;
pub const ELNRNG: u16 = 48;
pub const EUNATCH: u16 = 49;
pub const ENOCSI: u16 = 50;
pub const EL2HLT: u16 = 51;
pub const EBADE: u16 = 52;
pub const EBADR: u16 = 53;
pub const EXFULL: u16 = 54;
pub const ENOANO: u16 = 55;
pub const EBADRQC: u16 = 56;
pub const EBADSLT: u16 = 57;
pub const EBFONT: u16 = 59;
pub const ENOSTR: u16 = 60;
pub const ENODATA: u16 = 61;
pub const ETIME: u16 = 62;
pub const ENOSR: u16 = 63;
pub const ENONET: u16 = 64;
pub const ENOPKG: u16 = 65;
pub const EREMOTE: u16 = 66;
pub const ENOLINK: u16 = 67;
pub const EADV: u16 = 68;
pub const ESRMNT: u16 = 69;
pub const ECOMM: u16 = 70;
pub const EPROTO: u16 = 71;
pub const EMULTIHOP: u16 = 72;
pub const EDOTDOT: u16 = 73;
pub const EBADMSG: u16 = 74;
pub const EOVERFLOW: u16 = 75;
pub const ENOTUNIQ: u16 = 76;
pub const EBADFD: u16 = 77;
pub const EREMCHG: u16 = 78;
pub const ELIBACC: u16 = 79;
pub const ELIBBAD: u16 = 80;
pub const ELIBSCN: u16 = 81;
pub const ELIBMAX: u16 = 82;
pub const ELIBEXEC: u16 = 83;
pub const EILSEQ: u16 = 84;
pub const ERESTART: u16 = 85;
pub const ESTRPIPE: u16 = 86;
pub const EUSERS: u16 = 87;
pub const ENOTSOCK: u16 = 88;
pub const EDESTADDRREQ: u16 = 89;
pub const EMSGSIZE: u16 = 90;
pub const EPROTOTYPE: u16 = 91;
pub const ENOPROTOOPT: u16 = 92;
pub const EPROTONOSUPPORT: u16 = 93;
pub const ESOCKTNOSUPPORT: u16 = 94;
pub const EOPNOTSUPP: u16 = 95;
pub const EPFNOSUPPORT: u16 = 96;
pub const EAFNOSUPPORT: u16 = 97;
pub const EADDRINUSE: u16 = 98;
pub const EADDRNOTAVAIL: u16 = 99;
pub const ENETDOWN: u16 = 100;
pub const ENETUNREACH: u16 = 101;
pub const ENETRESET: u16 = 102;
pub const ECONNABORTED: u16 = 103;
pub const ECONNRESET: u16 = 104;
pub const ENOBUFS: u16 = 105;
pub const EISCONN: u16 = 106;
pub const ENOTCONN: u16 = 107;
pub const ESHUTDOWN: u16 = 108;
pub const ETOOMANYREFS: u16 = 109;
pub const ETIMEDOUT: u16 = 110;
pub const ECONNREFUSED: u16 = 111;
pub const EHOSTDOWN: u16 = 112;
pub const EHOSTUNREACH: u16 = 113;
pub const EALREADY: u16 = 114;
pub const EINPROGRESS: u16 = 115;
pub const ESTALE: u16 = 116;
pub const EUCLEAN: u16 = 117;
pub const ENOTNAM: u16 = 118;
pub const ENAVAIL: u16 = 119;
pub const EISNAM: u16 = 120;
pub const EREMOTEIO: u16 = 121;
pub const EDQUOT: u16 = 122;
pub const ENOMEDIUM: u16 = 123;
pub const EMEDIUMTYPE: u16 = 124;
pub const ECANCELED: u16 = 125;
pub const ENOKEY: u16 = 126;
pub const EKEYEXPIRED: u16 = 127;
pub const EKEYREVOKED: u16 = 128;
pub const EKEYREJECTED: u16 = 129;
pub const EOWNERDEAD: u16 = 130;
pub const ENOTRECOVERABLE: u16 = 131;
pub const ERFKILL: u16 = 132;
pub const EHWPOISON: u16 = 133;
pub const MAX_ERRNO: u16 = 4095;
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(i16);
impl Error {
pub const fn from_code(code: u16) -> Self {
if code == 0 || code > MAX_ERRNO {
panic!("invalid error code");
}
Error(-(code as i16))
}
pub const fn value(&self) -> i16 {
self.0
}
pub const fn code(&self) -> u16 {
(-self.0) as u16
}
pub const fn description(&self) -> Option<&'static str> {
Some(match self.code() {
EPERM => "Operation not permitted",
ENOENT => "No such file or directory",
ESRCH => "No such process",
EINTR => "Interrupted system call",
EIO => "I/O error",
ENXIO => "No such device or address",
E2BIG => "Argument list too long",
ENOEXEC => "Exec format error",
EBADF => "Bad file number",
ECHILD => "No child processes",
EAGAIN => "Try again",
ENOMEM => "Out of memory",
EACCES => "Permission denied",
EFAULT => "Bad address",
ENOTBLK => "Block device required",
EBUSY => "Device or resource busy",
EEXIST => "File exists",
EXDEV => "Cross-device link",
ENODEV => "No such device",
ENOTDIR => "Not a directory",
EISDIR => "Is a directory",
EINVAL => "Invalid argument",
ENFILE => "File table overflow",
EMFILE => "Too many open files",
ENOTTY => "Not a typewriter",
ETXTBSY => "Text file busy",
EFBIG => "File too large",
ENOSPC => "No space left on device",
ESPIPE => "Illegal seek",
EROFS => "Read-only file system",
EMLINK => "Too many links",
EPIPE => "Broken pipe",
EDOM => "Math argument out of domain of func",
ERANGE => "Math result not representable",
EDEADLK => "Resource deadlock would occur",
ENAMETOOLONG => "File name too long",
ENOLCK => "No record locks available",
ENOSYS => "Invalid system call number",
ENOTEMPTY => "Directory not empty",
ELOOP => "Too many symbolic links encountered",
ENOMSG => "No message of desired type",
EIDRM => "Identifier removed",
ECHRNG => "Channel number out of range",
EL2NSYNC => "Level 2 not synchronized",
EL3HLT => "Level 3 halted",
EL3RST => "Level 3 reset",
ELNRNG => "Link number out of range",
EUNATCH => "Protocol driver not attached",
ENOCSI => "No CSI structure available",
EL2HLT => "Level 2 halted",
EBADE => "Invalid exchange",
EBADR => "Invalid request descriptor",
EXFULL => "Exchange full",
ENOANO => "No anode",
EBADRQC => "Invalid request code",
EBADSLT => "Invalid slot",
EBFONT => "Bad font file format",
ENOSTR => "Device not a stream",
ENODATA => "No data available",
ETIME => "Timer expired",
ENOSR => "Out of streams resources",
ENONET => "Machine is not on the network",
ENOPKG => "Package not installed",
EREMOTE => "Object is remote",
ENOLINK => "Link has been severed",
EADV => "Advertise error",
ESRMNT => "Srmount error",
ECOMM => "Communication error on send",
EPROTO => "Protocol error",
EMULTIHOP => "Multihop attempted",
EDOTDOT => "RFS specific error",
EBADMSG => "Not a data message",
EOVERFLOW => "Value too large for defined data type",
ENOTUNIQ => "Name not unique on network",
EBADFD => "File descriptor in bad state",
EREMCHG => "Remote address changed",
ELIBACC => "Can not access a needed shared library",
ELIBBAD => "Accessing a corrupted shared library",
ELIBSCN => ".lib section in a.out corrupted",
ELIBMAX => "Attempting to link in too many shared libraries",
ELIBEXEC => "Cannot exec a shared library directly",
EILSEQ => "Illegal byte sequence",
ERESTART => "Interrupted system call should be restarted",
ESTRPIPE => "Streams pipe error",
EUSERS => "Too many users",
ENOTSOCK => "Socket operation on non-socket",
EDESTADDRREQ => "Destination address required",
EMSGSIZE => "Message too long",
EPROTOTYPE => "Protocol wrong type for socket",
ENOPROTOOPT => "Protocol not available",
EPROTONOSUPPORT => "Protocol not supported",
ESOCKTNOSUPPORT => "Socket type not supported",
EOPNOTSUPP => "Operation not supported on transport endpoint",
EPFNOSUPPORT => "Protocol family not supported",
EAFNOSUPPORT => "Address family not supported by protocol",
EADDRINUSE => "Address already in use",
EADDRNOTAVAIL => "Cannot assign requested address",
ENETDOWN => "Network is down",
ENETUNREACH => "Network is unreachable",
ENETRESET => "Network dropped connection because of reset",
ECONNABORTED => "Software caused connection abort",
ECONNRESET => "Connection reset by peer",
ENOBUFS => "No buffer space available",
EISCONN => "Transport endpoint is already connected",
ENOTCONN => "Transport endpoint is not connected",
ESHUTDOWN => "Cannot send after transport endpoint shutdown",
ETOOMANYREFS => "Too many references: cannot splice",
ETIMEDOUT => "Connection timed out",
ECONNREFUSED => "Connection refused",
EHOSTDOWN => "Host is down",
EHOSTUNREACH => "No route to host",
EALREADY => "Operation already in progress",
EINPROGRESS => "Operation now in progress",
ESTALE => "Stale file handle",
EUCLEAN => "Structure needs cleaning",
ENOTNAM => "Not a XENIX named type file",
ENAVAIL => "No XENIX semaphores available",
EISNAM => "Is a named type file",
EREMOTEIO => "Remote I/O error",
EDQUOT => "Quota exceeded",
ENOMEDIUM => "No medium found",
EMEDIUMTYPE => "Wrong medium type",
ECANCELED => "Operation Canceled",
ENOKEY => "Required key not available",
EKEYEXPIRED => "Key has expired",
EKEYREVOKED => "Key has been revoked",
EKEYREJECTED => "Key was rejected by service",
EOWNERDEAD => "Owner died",
ENOTRECOVERABLE => "State not recoverable",
ERFKILL => "Operation not possible due to RF-kill",
EHWPOISON => "Memory page has hardware error",
_ => return None,
})
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if let Some(description) = self.description() {
f.write_str(description)
} else {
write!(f, "Unknown error {}", self.code())
}
}
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self, f)
}
}
impl TryFrom<u16> for Error {
type Error = ();
fn try_from(value: u16) -> CoreResult<Self, Self::Error> {
if value > u16::MAX - MAX_ERRNO {
Ok(Error(value as i16))
} else {
Err(())
}
}
}
impl TryFrom<i16> for Error {
type Error = ();
fn try_from(value: i16) -> CoreResult<Self, Self::Error> {
TryFrom::try_from(value as u16)
}
}
impl TryFrom<u32> for Error {
type Error = ();
fn try_from(value: u32) -> CoreResult<Self, Self::Error> {
if value > u32::MAX - u32::from(MAX_ERRNO) {
Ok(Error(value as i16))
} else {
Err(())
}
}
}
impl TryFrom<i32> for Error {
type Error = ();
fn try_from(value: i32) -> CoreResult<Self, Self::Error> {
TryFrom::try_from(value as u32)
}
}
impl TryFrom<usize> for Error {
type Error = ();
fn try_from(value: usize) -> CoreResult<Self, Self::Error> {
if value > usize::MAX - usize::from(MAX_ERRNO) {
Ok(Error(value as i16))
} else {
Err(())
}
}
}
impl TryFrom<isize> for Error {
type Error = ();
fn try_from(value: isize) -> CoreResult<Self, Self::Error> {
TryFrom::try_from(value as usize)
}
}
pub type Result<T> = CoreResult<T, Error>;
pub fn result_from_value<T>(value: T) -> Result<T>
where
T: Copy,
Error: TryFrom<T>,
{
match Error::try_from(value) {
Ok(err) => Err(err),
Err(_) => Ok(value),
}
}
pub fn unit_result_from_value<T>(value: T) -> Result<()>
where
T: Copy,
Error: TryFrom<T>,
{
match Error::try_from(value) {
Ok(err) => Err(err),
Err(_) => Ok(()),
}
}