use std::mem::ManuallyDrop;
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::ffi_types::*;
use crate::prelude::*;
#[must_use]
pub(crate) unsafe fn vt<T>(obj: &impl ole_IUnknown) -> &T {
let ppvt = obj.ptr() as *mut *mut T;
unsafe { &**ppvt }
}
pub(crate) struct HrRet(pub(crate) HRES);
impl HrRet {
#[must_use]
pub(crate) const fn to_hrresult(self) -> HrResult<()> {
match unsafe { co::HRESULT::from_raw(self.0) } {
co::HRESULT::S_OK => Ok(()),
hr => Err(hr),
}
}
#[must_use]
pub(crate) const fn to_bool_hrresult(self) -> HrResult<bool> {
match unsafe { co::HRESULT::from_raw(self.0) } {
co::HRESULT::S_OK => Ok(true),
co::HRESULT::S_FALSE => Ok(false),
hr => Err(hr),
}
}
}
#[must_use]
pub(crate) fn hrresult_to_hres<T>(hrr: HrResult<T>) -> HRES {
match hrr {
Ok(_) => co::HRESULT::S_OK.raw(),
Err(e) => e.raw(),
}
}
#[must_use]
pub(crate) fn htaskmem_ptr_to_str(p: *mut u16) -> String {
let wstr = unsafe { WString::from_wchars_nullt(p) };
let _ = unsafe { CoTaskMemFreeGuard::new(p as _, 0) };
wstr.to_string()
}
#[must_use]
pub(crate) fn box_impl_of<T>(p: COMPTR) -> ManuallyDrop<Box<T>> {
let pp = p as *mut *mut T;
let box_impl = ManuallyDrop::new(unsafe { Box::from_raw(*pp) });
box_impl
}
#[must_use]
pub(crate) fn anyresult_to_hresult<T>(res: AnyResult<T>) -> HrResult<T> {
res.map_err(|err| {
if let Some(hr) = err.downcast_ref::<co::HRESULT>() {
*hr
} else if let Some(err) = err.downcast_ref::<co::ERROR>() {
err.to_hresult()
} else {
HWND::NULL
.MessageBox(
&format!("Unhandled error: {}", err.to_string()),
"Unhandled error in COM impl",
co::MB::ICONERROR,
)
.unwrap();
co::HRESULT::E_UNEXPECTED
}
})
}