#![no_std]
use core::fmt;
use core::slice;
use core::str;
#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Error {
pub errno: i32,
}
impl Error {
pub const fn new(errno: i32) -> Self {
Self { errno }
}
pub fn last_error() -> Self {
Self { errno: errno() }
}
}
impl Default for Error {
fn default() -> Self {
Error::new(-1)
}
}
impl From<i32> for Error {
fn from(i32: i32) -> Self {
Self::new(i32)
}
}
impl From<Error> for Result<(), Error> {
fn from(err: Error) -> Self {
if err.errno == 0 {
Ok(())
} else {
Err(err)
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}, {}", self.errno, unsafe { errmsg(self.errno) })
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}, {}", self.errno, unsafe { errmsg(self.errno) })
}
}
cfg_if::cfg_if! {
if #[cfg(unix)] {
#[link(name = "c")]
extern "C" {
#[cfg(any(
target_os = "linux",
target_os = "redox",
target_os = "dragonfly",
target_os = "fuchsia"
))]
#[link_name = "__errno_location"]
fn errno_location() -> *mut i32;
#[cfg(any(target_os = "android", target_os = "netbsd", target_os = "openbsd"))]
#[link_name = "__errno"]
fn errno_location() -> *mut i32;
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "freebsd"))]
#[link_name = "__error"]
fn errno_location() -> *mut i32;
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
#[link_name = "___errno"]
fn errno_location() -> *mut i32;
#[cfg(any(target_os = "haiku"))]
#[link_name = "_errnop"]
fn errno_location() -> *mut i32;
fn strerror(errno: i32) -> *const u8;
fn strlen(s: *const u8) -> usize;
}
pub fn errno() -> i32 {
unsafe { *errno_location() }
}
pub fn set_errno(errno: i32) {
unsafe { *errno_location() = errno };
}
pub unsafe fn errmsg<'a>(errno: i32) -> &'a str {
let s = strerror(errno);
let len = strlen(s);
str::from_utf8_unchecked(slice::from_raw_parts(s, len))
}
} else if #[cfg(windows)] {
pub fn errmsg<'a>(errno: i32) -> &'a str {
"unknown"
}
#[link(name = "Kernel32")]
extern "C" {
#[link_name = "GetLastError"]
pub fn errno() -> i32;
#[link_name = "SetLastError"]
pub fn set_errno(errno: i32);
}
}
}
pub mod prelude {
pub const EPERM: i32 = 1;
pub const ENOENT: i32 = 2;
pub const EAGAIN: i32 = 11;
pub const ENOMEM: i32 = 12;
pub const EEXIST: i32 = 17;
pub const EINVAL: i32 = 22;
pub const ERANGE: i32 = 34;
pub const ETIMEDOUT: i32 = 110;
pub const ECANCELED: i32 = 125;
}