use super::*;
use bindings::Windows::Foundation::{IReference, IStringable, PropertyValue};
#[repr(transparent)]
#[derive(Clone, PartialEq, Eq)]
pub struct Object(IUnknown);
impl Object {
pub fn type_name(&self) -> Result<HString> {
unsafe {
let mut abi = std::ptr::null_mut();
(self.vtable().4)(self.abi(), &mut abi).ok()?;
Ok(std::mem::transmute(abi))
}
}
}
#[repr(C)]
pub struct Object_vtable(
pub unsafe extern "system" fn(this: RawPtr, iid: &Guid, interface: *mut RawPtr) -> ErrorCode,
pub unsafe extern "system" fn(this: RawPtr) -> u32,
pub unsafe extern "system" fn(this: RawPtr) -> u32,
pub unsafe extern "system" fn(
this: RawPtr,
count: *mut u32,
values: *mut *mut Guid,
) -> ErrorCode,
pub unsafe extern "system" fn(this: RawPtr, value: *mut RawPtr) -> ErrorCode,
pub unsafe extern "system" fn(this: RawPtr, value: *mut i32) -> ErrorCode,
);
unsafe impl Interface for Object {
type Vtable = Object_vtable;
const IID: Guid = Guid::from_values(
0xAF86_E2E0,
0xB12D,
0x4C6A,
[0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90],
);
}
unsafe impl RuntimeType for Object {
type DefaultType = Option<Self>;
const SIGNATURE: crate::ConstBuffer =
crate::ConstBuffer::from_slice(b"cinterface(IInspectable)");
}
impl std::fmt::Debug for Object {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = self
.cast::<IStringable>()
.and_then(|s| s.ToString())
.or_else(|_| self.type_name())
.unwrap_or_default();
write!(f, "{:?} {}", self.0, name)
}
}
macro_rules! primitive_boxed_type {
($(($t:ty, $m:ident)),+) => {
$(impl std::convert::TryFrom<$t> for Object {
type Error = Error;
fn try_from(value: $t) -> Result<Self> {
PropertyValue::$m(value)
}
}
impl std::convert::TryFrom<Object> for $t {
type Error = Error;
fn try_from(value: Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<$t>>(&value)?.Value()
}
}
impl std::convert::TryFrom<&Object> for $t {
type Error = Error;
fn try_from(value: &Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<$t>>(value)?.Value()
}
})*
};
}
primitive_boxed_type! {
(bool, CreateBoolean),
(u8, CreateUInt8),
(i16, CreateInt16),
(u16, CreateUInt16),
(i32, CreateInt32),
(u32, CreateUInt32),
(i64, CreateInt64),
(u64, CreateUInt64),
(f32, CreateSingle),
(f64, CreateDouble)
}
impl std::convert::TryFrom<&str> for Object {
type Error = Error;
fn try_from(value: &str) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<HString> for Object {
type Error = Error;
fn try_from(value: HString) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<&HString> for Object {
type Error = Error;
fn try_from(value: &HString) -> Result<Self> {
PropertyValue::CreateString(value)
}
}
impl std::convert::TryFrom<Object> for HString {
type Error = Error;
fn try_from(value: Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<HString>>(&value)?.Value()
}
}
impl std::convert::TryFrom<&Object> for HString {
type Error = Error;
fn try_from(value: &Object) -> Result<Self> {
<Object as Interface>::cast::<IReference<HString>>(value)?.Value()
}
}