#![deny(clippy::missing_docs_in_private_items)]
#![deny(missing_docs)]
use microseh::Exception;
use std::{borrow::Cow, error::Error as stderr, fmt};
use windows::core::{Error as WErr, HRESULT};
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, PartialEq)]
#[repr(u8)]
pub enum Error {
ReadLocked = 0,
WriteLocked = 1,
Uninitialized = 2,
MaxReaders = 3,
NotEnoughMemory = 4,
MMF_NotFound = 5,
LockViolation = 6,
MaxTriesReached = 7,
LargePagePermissionError = 8,
GeneralFailure = 253,
OS_Err(WErr) = 254,
OS_OK(WErr) = 255,
}
impl stderr for Error {
fn source(&self) -> Option<&(dyn stderr + 'static)> {
match self {
Self::OS_Err(w) => Some(w),
_ => None,
}
}
}
impl From<HRESULT> for Error {
fn from(value: HRESULT) -> Self {
match value {
HRESULT(30) => Self::ReadLocked,
HRESULT(19) => Self::WriteLocked,
HRESULT(8) => Self::NotEnoughMemory,
HRESULT(9) => Self::Uninitialized,
HRESULT(2) => Self::MMF_NotFound,
HRESULT(33) => Self::LockViolation,
HRESULT(0) => Self::OS_OK(value.into()),
_ => Self::OS_Err(value.into()),
}
}
}
impl From<i32> for Error {
fn from(value: i32) -> Self {
Self::from(HRESULT(value))
}
}
impl From<u32> for Error {
fn from(value: u32) -> Self {
Self::from(value as i32)
}
}
impl From<WErr> for Error {
fn from(value: WErr) -> Self {
Self::from(value.code())
}
}
impl From<Exception> for Error {
fn from(value: Exception) -> Self {
Self::from(HRESULT(value.code() as u32 as i32))
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let text: Cow<str> = match self {
Self::OS_OK(_) => Cow::from("Task failed successfully!"),
Self::WriteLocked => Cow::from("Memory Mapped File was locked for writing"),
Self::ReadLocked => Cow::from("Memory Mapped File was locked for reading"),
Self::LockViolation => Cow::from("MMF was locked between checking and acquiring the lock!"),
Self::NotEnoughMemory => Cow::from("The requested write was larger than the buffer size"),
Self::MMF_NotFound => Cow::from("E002: No memory mapped file has been opened yet!"),
Self::Uninitialized => Cow::from("Memory Mapped File was not yet initialized"),
Self::MaxReaders => Cow::from("The maximum amount of readers is already registered"),
Self::MaxTriesReached => Cow::from("The maximum amount of tries was reached spinning"),
Self::GeneralFailure => Cow::from("No idea what the hell happened here..."),
Self::OS_Err(c) => Cow::from(format!("E{c:02}: Generic OS Error")),
Self::LargePagePermissionError => Cow::from("Could not acquire SeLockMemoryPrivilege!"),
};
write!(
f,
"{text}: {}",
self.source().map(|e| Cow::from(e.to_string())).unwrap_or(Cow::from("occurred in this crate."))
)
}
}
pub type MMFResult<T> = Result<T, Error>;