use thiserror::Error;
use winapi::shared::winerror::{
CLASS_E_NOAGGREGATION, DISP_E_UNKNOWNLCID, DISP_E_UNKNOWNNAME, E_NOINTERFACE, E_OUTOFMEMORY,
E_POINTER, HRESULT, REGDB_E_CLASSNOTREG,
};
use win_variant::{VariantArgError, VariantResultError};
#[derive(Debug, Error)]
pub enum HResultError {
#[error("class is not registered")]
ClassNotRegister,
#[error("class not part of aggregate")]
ClassNotPartOfAggregate,
#[error("unkown name when performing lookup on dispatch interface")]
UnknownDispatchName,
#[error("unkown local id")]
UnknownLocalID,
#[error("class does not implement an interface")]
NoInterface,
#[error("not enough memory to perform operation")]
NotEnoughMemory,
#[error("null pointer provided when expecting an initialized one")]
NullPointer,
#[error("unknown HRESULT `{0}`")]
Unknown(HRESULT),
}
#[derive(Debug, Error)]
pub enum Error {
#[error("hresult error: {0}")]
HResult(HResultError),
#[error("unknown interface pointer is null")]
NullUnknownPointer,
#[error("dispath interface pointer is null")]
NullDispatchPointer,
#[error("failed to convert string to wide char string: {0}")]
ToWideCharStringError(widestring::NulError<u16>),
#[error("variant arg error: {0}")]
VariantArgError(VariantArgError),
#[error("failed convert variant into result: {0}")]
VariantResultError(VariantResultError),
}
impl From<HRESULT> for Error {
fn from(e: HRESULT) -> Self {
let hr = match e {
REGDB_E_CLASSNOTREG => HResultError::ClassNotRegister,
CLASS_E_NOAGGREGATION => HResultError::ClassNotPartOfAggregate,
DISP_E_UNKNOWNNAME => HResultError::UnknownDispatchName,
DISP_E_UNKNOWNLCID => HResultError::UnknownLocalID,
E_NOINTERFACE => HResultError::NoInterface,
E_OUTOFMEMORY => HResultError::NotEnoughMemory,
E_POINTER => HResultError::NullPointer,
_ => HResultError::Unknown(e),
};
Error::HResult(hr)
}
}
impl From<widestring::NulError<u16>> for Error {
fn from(e: widestring::NulError<u16>) -> Self {
Error::ToWideCharStringError(e)
}
}
impl From<VariantResultError> for Error {
fn from(e: VariantResultError) -> Self {
Error::VariantResultError(e)
}
}
impl From<VariantArgError> for Error {
fn from(e: VariantArgError) -> Self {
Error::VariantArgError(e)
}
}