use winapi::shared::ntstatus::*;
use winapi::shared::winerror::*;
use winapi::um::errhandlingapi::GetLastError;
use core::fmt::{self, Debug, Formatter};
pub(crate) trait ResultErrorExt<R> { fn unerr(self, err: u32, remap: R) -> Self; }
impl<R> ResultErrorExt<R> for Result<R, Error> { fn unerr(self, err: u32, remap: R) -> Self { match self { Err(e) if e == err => Ok(remap), r => r } } }
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct Error(pub(crate) u32);
impl Error {
pub fn get_last() -> Self { Self(unsafe { GetLastError() }) }
pub fn get_last_if(error: bool) -> Result<(), Self> { if !error { Ok(()) } else { Err(Self::get_last()) } }
pub fn friendly(self) -> &'static str {
match self.0 {
NO_ERROR => "NO_ERROR", ERROR_FILE_NOT_FOUND => "ERROR_FILE_NOT_FOUND", ERROR_ACCESS_DENIED => "ERROR_ACCESS_DENIED", ERROR_INVALID_HANDLE => "ERROR_INVALID_HANDLE", ERROR_BAD_ENVIRONMENT => "ERROR_BAD_ENVIRONMENT", ERROR_BAD_LENGTH => "ERROR_BAD_LENGTH", ERROR_NOT_SUPPORTED => "ERROR_NOT_SUPPORTED", ERROR_INVALID_PARAMETER => "ERROR_INVALID_PARAMETER", ERROR_EXCL_SEM_ALREADY_OWNED => "ERROR_EXCL_SEM_ALREADY_OWNED", ERROR_INSUFFICIENT_BUFFER => "ERROR_INSUFFICIENT_BUFFER", ERROR_BAD_ARGUMENTS => "ERROR_BAD_ARGUMENTS", ERROR_BAD_PATHNAME => "ERROR_BAD_PATHNAME", ERROR_BUSY => "ERROR_BUSY", ERROR_PARTIAL_COPY => "ERROR_PARTIAL_COPY", ERROR_NO_TOKEN => "ERROR_NO_TOKEN", ERROR_PRIVILEGE_NOT_HELD => "ERROR_PRIVILEGE_NOT_HELD", ERROR_INVALID_SUB_AUTHORITY => "ERROR_INVALID_SUB_AUTHORITY", ERROR_INVALID_ACL => "ERROR_INVALID_ACL", ERROR_INVALID_SID => "ERROR_INVALID_SID", ERROR_INVALID_SECURITY_DESCR => "ERROR_INVALID_SECURITY_DESCR", ERROR_BAD_INHERITANCE_ACL => "ERROR_BAD_INHERITANCE_ACL", ERROR_INVALID_ID_AUTHORITY => "ERROR_INVALID_ID_AUTHORITY", ERROR_ALLOTTED_SPACE_EXCEEDED => "ERROR_ALLOTTED_SPACE_EXCEEDED", ERROR_BAD_TOKEN_TYPE => "ERROR_BAD_TOKEN_TYPE", ERROR_INCORRECT_SIZE => "ERROR_INCORRECT_SIZE", ERROR_DYNAMIC_CODE_BLOCKED => "ERROR_DYNAMIC_CODE_BLOCKED", 1657 => "ERROR_STRICT_CFG_VIOLATION", ERROR_INVALID_ENVIRONMENT => "ERROR_INVALID_ENVIRONMENT", _ => match self.0 as _ {
E_STRING_NOT_NULL_TERMINATED => "E_STRING_NOT_NULL_TERMINATED", STATUS_INVALID_HANDLE => "STATUS_INVALID_HANDLE", STATUS_ACCESS_DENIED => "STATUS_ACCESS_DENIED", STATUS_BAD_IMPERSONATION_LEVEL => "STATUS_BAD_IMPERSONATION_LEVEL", STATUS_DLL_NOT_FOUND => "STATUS_DLL_NOT_FOUND", STATUS_DLL_INIT_FAILED => "STATUS_DLL_INIT_FAILED", _ if self.0 & 0xF000_0000 == 0x8000_0000 => "E_???", _ if self.0 & 0xF000_0000 == 0xC000_0000 => "STATUS_???", _ => "ERROR_???", },
}
}
}
impl Debug for Error {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
if self.0 < 0x8000_0000 {
write!(fmt, "Error({} {})", self.0, self.friendly())
} else {
write!(fmt, "Error(0x{:X} {})", self.0, self.friendly())
}
}
}
impl From<Error> for i32 { fn from(err: Error) -> Self { err.0 as _ } }
impl From<Error> for u32 { fn from(err: Error) -> Self { err.0 as _ } }
impl From<Error> for crate::io::Error { fn from(err: Error) -> Self { Self::from_raw_os_error(err.into()) } }
impl From<i32> for Error { fn from(err: i32 ) -> Self { Self(err as _) } }
impl From<u32> for Error { fn from(err: u32 ) -> Self { Self(err as _) } }
impl PartialEq<i32> for Error { fn eq(&self, other: &i32) -> bool { *self == Error::from(*other) } }
impl PartialEq<u32> for Error { fn eq(&self, other: &u32) -> bool { *self == Error::from(*other) } }
impl PartialEq<Error> for i32 { fn eq(&self, other: &Error) -> bool { Error::from(*self) == *other } }
impl PartialEq<Error> for u32 { fn eq(&self, other: &Error) -> bool { Error::from(*self) == *other } }