1 | use super::*; |
2 | |
3 | /// A WinRT object that may be used as a polymorphic stand-in for any WinRT class, interface, or boxed value. |
4 | /// [`IInspectable`] represents the |
5 | /// [IInspectable](https://docs.microsoft.com/en-us/windows/win32/api/inspectable/nn-inspectable-iinspectable) |
6 | /// interface. |
7 | #[repr (transparent)] |
8 | #[derive (Clone, PartialEq, Eq)] |
9 | pub struct IInspectable(pub IUnknown); |
10 | |
11 | impl IInspectable { |
12 | /// Returns the canonical type name for the underlying object. |
13 | pub fn GetRuntimeClassName(&self) -> Result<HSTRING> { |
14 | unsafe { |
15 | let mut abi: *mut c_void = std::ptr::null_mut(); |
16 | (self.vtable().GetRuntimeClassName)(std::mem::transmute_copy(self), &mut abi).ok()?; |
17 | Ok(std::mem::transmute(src:abi)) |
18 | } |
19 | } |
20 | } |
21 | |
22 | #[doc (hidden)] |
23 | #[repr (C)] |
24 | pub struct IInspectable_Vtbl { |
25 | pub base: IUnknown_Vtbl, |
26 | pub GetIids: unsafe extern "system" fn(this: *mut std::ffi::c_void, count: *mut u32, values: *mut *mut GUID) -> HRESULT, |
27 | pub GetRuntimeClassName: unsafe extern "system" fn(this: *mut std::ffi::c_void, value: *mut *mut std::ffi::c_void) -> HRESULT, |
28 | pub GetTrustLevel: unsafe extern "system" fn(this: *mut std::ffi::c_void, value: *mut i32) -> HRESULT, |
29 | } |
30 | |
31 | unsafe impl Interface for IInspectable { |
32 | type Vtable = IInspectable_Vtbl; |
33 | } |
34 | |
35 | unsafe impl ComInterface for IInspectable { |
36 | const IID: GUID = GUID::from_u128(uuid:0xaf86e2e0_b12d_4c6a_9c5a_d7aa65101e90); |
37 | } |
38 | |
39 | impl CanInto<IUnknown> for IInspectable {} |
40 | |
41 | impl RuntimeType for IInspectable { |
42 | const SIGNATURE: crate::imp::ConstBuffer = crate::imp::ConstBuffer::from_slice(b"cinterface(IInspectable)" ); |
43 | } |
44 | |
45 | impl RuntimeName for IInspectable {} |
46 | |
47 | #[cfg (feature = "implement" )] |
48 | impl IInspectable_Vtbl { |
49 | pub const fn new<Identity: IUnknownImpl, Name: RuntimeName, const OFFSET: isize>() -> Self { |
50 | unsafe extern "system" fn GetIids(_: *mut std::ffi::c_void, count: *mut u32, values: *mut *mut GUID) -> HRESULT { |
51 | // Note: even if we end up implementing this in future, it still doesn't need a this pointer |
52 | // since the data to be returned is type- not instance-specific so can be shared for all |
53 | // interfaces. |
54 | *count = 0; |
55 | *values = std::ptr::null_mut(); |
56 | HRESULT(0) |
57 | } |
58 | unsafe extern "system" fn GetRuntimeClassName<T: RuntimeName>(_: *mut std::ffi::c_void, value: *mut *mut std::ffi::c_void) -> HRESULT { |
59 | let h: HSTRING = T::NAME.into(); // TODO: should be try_into |
60 | *value = std::mem::transmute(h); |
61 | HRESULT(0) |
62 | } |
63 | unsafe extern "system" fn GetTrustLevel(_: *mut std::ffi::c_void, value: *mut i32) -> HRESULT { |
64 | // Note: even if we end up implementing this in future, it still doesn't need a this pointer |
65 | // since the data to be returned is type- not instance-specific so can be shared for all |
66 | // interfaces. |
67 | *value = 0; |
68 | HRESULT(0) |
69 | } |
70 | Self { base: IUnknown_Vtbl::new::<Identity, OFFSET>(), GetIids, GetRuntimeClassName: GetRuntimeClassName::<Name>, GetTrustLevel } |
71 | } |
72 | } |
73 | |
74 | impl std::fmt::Debug for IInspectable { |
75 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
76 | // Attempts to retrieve the string representation of the object via the |
77 | // IStringable interface. If that fails, it will use the canonical type |
78 | // name to give some idea of what the object represents. |
79 | let name: HSTRING = <Self as ComInterface>::cast::<imp::IStringable>(self).and_then(|s| s.ToString()).or_else(|_| self.GetRuntimeClassName()).unwrap_or_default(); |
80 | write!(f, " \"{}\"" , name) |
81 | } |
82 | } |
83 | |
84 | macro_rules! primitive_boxed_type { |
85 | ($(($t:ty, $m:ident)),+) => { |
86 | $(impl std::convert::TryFrom<$t> for IInspectable { |
87 | type Error = Error; |
88 | fn try_from(value: $t) -> Result<Self> { |
89 | imp::PropertyValue::$m(value) |
90 | } |
91 | } |
92 | impl std::convert::TryFrom<IInspectable> for $t { |
93 | type Error = Error; |
94 | fn try_from(value: IInspectable) -> Result<Self> { |
95 | <IInspectable as ComInterface>::cast::<imp::IReference<$t>>(&value)?.Value() |
96 | } |
97 | } |
98 | impl std::convert::TryFrom<&IInspectable> for $t { |
99 | type Error = Error; |
100 | fn try_from(value: &IInspectable) -> Result<Self> { |
101 | <IInspectable as ComInterface>::cast::<imp::IReference<$t>>(value)?.Value() |
102 | } |
103 | })* |
104 | }; |
105 | } |
106 | primitive_boxed_type! { |
107 | (bool, CreateBoolean), |
108 | (u8, CreateUInt8), |
109 | (i16, CreateInt16), |
110 | (u16, CreateUInt16), |
111 | (i32, CreateInt32), |
112 | (u32, CreateUInt32), |
113 | (i64, CreateInt64), |
114 | (u64, CreateUInt64), |
115 | (f32, CreateSingle), |
116 | (f64, CreateDouble) |
117 | } |
118 | impl std::convert::TryFrom<&str> for IInspectable { |
119 | type Error = Error; |
120 | fn try_from(value: &str) -> Result<Self> { |
121 | let value: HSTRING = value.into(); |
122 | imp::PropertyValue::CreateString(&value) |
123 | } |
124 | } |
125 | impl std::convert::TryFrom<HSTRING> for IInspectable { |
126 | type Error = Error; |
127 | fn try_from(value: HSTRING) -> Result<Self> { |
128 | imp::PropertyValue::CreateString(&value) |
129 | } |
130 | } |
131 | impl std::convert::TryFrom<&HSTRING> for IInspectable { |
132 | type Error = Error; |
133 | fn try_from(value: &HSTRING) -> Result<Self> { |
134 | imp::PropertyValue::CreateString(value) |
135 | } |
136 | } |
137 | impl std::convert::TryFrom<IInspectable> for HSTRING { |
138 | type Error = Error; |
139 | fn try_from(value: IInspectable) -> Result<Self> { |
140 | <IInspectable as ComInterface>::cast::<imp::IReference<HSTRING>>(&value)?.Value() |
141 | } |
142 | } |
143 | impl std::convert::TryFrom<&IInspectable> for HSTRING { |
144 | type Error = Error; |
145 | fn try_from(value: &IInspectable) -> Result<Self> { |
146 | <IInspectable as ComInterface>::cast::<imp::IReference<HSTRING>>(self:value)?.Value() |
147 | } |
148 | } |
149 | |