use crate::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ErrorKind {
UnexpectedEof,
InvalidInput,
NotFound,
PermissionDenied,
AlreadyExists,
Interrupted,
Other,
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
code: i32,
msg: &'static str,
}
pub type Result<T> = core::result::Result<T, Error>;
impl Error {
#[inline]
pub fn last_os_error() -> Self {
Self {
kind: ErrorKind::Other,
code: last_error_code(),
msg: "",
}
}
#[inline]
pub fn from_raw_os_error(code: i32) -> Self {
Self {
kind: ErrorKind::Other,
code,
msg: "",
}
}
#[inline]
pub fn other(msg: &'static str) -> Self {
Self {
kind: ErrorKind::Other,
code: 0,
msg,
}
}
#[inline]
pub fn new(kind: ErrorKind, msg: &'static str) -> Self {
Self { kind, code: 0, msg }
}
#[inline]
pub fn raw_os_error(&self) -> Option<i32> {
if self.code != 0 {
Some(self.code)
} else {
None
}
}
#[inline]
pub fn kind(&self) -> ErrorKind {
self.kind
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.code != 0 {
write!(f, "os error {}", self.code)
} else {
f.write_str(self.msg)
}
}
}
impl core::error::Error for Error {}
#[cfg(all(target_os = "linux", not(target_family = "wasm")))]
fn last_error_code() -> i32 {
unsafe extern "C" {
fn __errno_location() -> *mut i32;
}
unsafe { *__errno_location() }
}
#[cfg(all(
any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
),
not(target_family = "wasm"),
))]
fn last_error_code() -> i32 {
unsafe extern "C" {
fn __error() -> *mut i32;
}
unsafe { *__error() }
}
#[cfg(all(windows, not(target_family = "wasm")))]
fn last_error_code() -> i32 {
unsafe extern "system" {
fn GetLastError() -> u32;
}
unsafe { GetLastError() as i32 }
}
#[cfg(target_family = "wasm")]
fn last_error_code() -> i32 {
0
}
pub trait AsyncRead {
async fn read(&mut self, buf: Vec<u8>) -> (Result<usize>, Vec<u8>);
}
pub trait AsyncWrite {
async fn write(&mut self, buf: Vec<u8>) -> (Result<usize>, Vec<u8>);
}