use std::fmt;
use windows_sys::Win32::Foundation::WIN32_ERROR;
#[derive(Debug, Clone)]
pub struct Error {
pub call: &'static str,
pub code: u32,
pub detail: Option<String>,
}
impl Error {
pub(crate) fn last(call: &'static str) -> Self {
Self {
call,
code: unsafe { windows_sys::Win32::Foundation::GetLastError() },
detail: None,
}
}
pub(crate) fn code(call: &'static str, code: WIN32_ERROR) -> Self {
Self {
call,
code,
detail: None,
}
}
pub(crate) fn hresult(call: &'static str, hr: i32) -> Self {
Self {
call,
code: hr as u32,
detail: None,
}
}
pub(crate) fn saying(call: &'static str, detail: impl Into<String>) -> Self {
Self {
call,
code: 0,
detail: Some(detail.into()),
}
}
pub fn is_not_found(&self) -> bool {
const ERROR_FILE_NOT_FOUND: u32 = 2;
const ERROR_SERVICE_DOES_NOT_EXIST: u32 = 1060;
matches!(
self.code,
ERROR_FILE_NOT_FOUND | ERROR_SERVICE_DOES_NOT_EXIST
)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.detail {
Some(detail) => write!(f, "{}: {detail}", self.call),
None => write!(f, "{} failed (0x{:08X})", self.call, self.code),
}
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;