use crate::os::win::ComPtr;
use winapi::shared::{ntdef::HRESULT, winerror::SUCCEEDED};
pub fn call<TFunction, TFunctionValue, T>(function: TFunction) -> Result<T, std::io::Error>
where
TFunction: FnOnce(*mut T) -> TFunctionValue,
TFunctionValue: HrStyleFunction,
{
hr_call(function).map_err(TFunctionValue::error)
}
pub fn hr_call<TFunction, TFunctionValue, T>(function: TFunction) -> Result<T, TFunctionValue>
where
TFunction: FnOnce(*mut T) -> TFunctionValue,
TFunctionValue: HrStyleFunction,
{
let mut value = unsafe { std::mem::zeroed::<T>() };
let returned = function(&mut value);
match HrStyleFunction::ok(returned) {
true => Ok(value),
false => Err(returned),
}
}
pub fn com_call<TFunction, TFunctionValue, T>(function: TFunction) -> Result<ComPtr<T>, std::io::Error>
where
TFunction: FnOnce(*mut *mut T) -> TFunctionValue,
TFunctionValue: HrStyleFunction,
{
com_hr_call(function).map_err(TFunctionValue::error)
}
pub fn com_hr_call<TFunction, TFunctionValue, T>(function: TFunction) -> Result<ComPtr<T>, TFunctionValue>
where
TFunction: FnOnce(*mut *mut T) -> TFunctionValue,
TFunctionValue: HrStyleFunction,
{
let mut value = std::ptr::null_mut();
let returned = function(&mut value);
match HrStyleFunction::ok(returned) {
true => Ok(unsafe { ComPtr::new(value) }),
false => Err(returned),
}
}
pub trait HrStyleFunction: Copy {
fn ok(self: Self) -> bool;
fn error(self: Self) -> std::io::Error;
}
impl HrStyleFunction for HRESULT {
fn ok(self: HRESULT) -> bool {
SUCCEEDED(self)
}
fn error(self: HRESULT) -> std::io::Error {
std::io::Error::from_raw_os_error(self)
}
}
impl HrStyleFunction for bool {
fn ok(self: bool) -> bool {
self
}
fn error(self: bool) -> std::io::Error {
std::io::Error::last_os_error()
}
}
impl HrStyleFunction for () {
fn ok(self: ()) -> bool {
true
}
fn error(self: ()) -> std::io::Error {
unreachable!();
}
}