winsafe/oleaut/structs/
variant.rs1#![allow(non_snake_case)]
2
3use std::mem::ManuallyDrop;
4
5use crate::co;
6use crate::oleaut::ffi;
7use crate::prelude::*;
8
9#[repr(C)]
19pub struct VARIANT {
20 vt: co::VT,
21 wReserved1: u16,
22 wReserved2: u16,
23 wReserved3: u16,
24 data: [u8; 16],
25}
26
27impl Drop for VARIANT {
28 fn drop(&mut self) {
29 if self.vt() != co::VT::EMPTY {
30 unsafe { ffi::VariantClear(self as *mut _ as _); } }
32 }
33}
34
35impl Default for VARIANT {
36 fn default() -> Self {
37 let mut obj = unsafe { std::mem::zeroed::<Self>() };
38 unsafe { ffi::VariantInit(&mut obj as *mut _ as _); }
39 obj
40 }
41}
42
43impl oleaut_Variant for VARIANT {
44 fn raw(&self) -> &[u8; 16] {
45 &self.data
46 }
47
48 unsafe fn from_raw(vt: co::VT, data: &[u8]) -> Self {
49 let mut obj = Self::default();
50 obj.vt = vt;
51 data.iter()
52 .zip(&mut obj.data)
53 .for_each(|(src, dest)| *dest = *src);
54 obj
55 }
56
57 fn vt(&self) -> co::VT {
58 self.vt
59 }
60}
61
62impl VARIANT {
63 #[must_use]
70 pub fn new_idispatch(val: &impl oleaut_IDispatch) -> Self {
71 let mut cloned = val.clone();
72 let ptr = cloned.leak() as usize;
73 unsafe { Self::from_raw(co::VT::DISPATCH, &ptr.to_ne_bytes()) }
74 }
75
76 #[must_use]
83 pub fn idispatch<T>(&self) -> Option<T>
84 where T: oleaut_IDispatch,
85 {
86 if self.vt() == co::VT::DISPATCH {
87 let ptr = usize::from_ne_bytes(self.raw()[..8].try_into().unwrap());
88 let obj = ManuallyDrop::new(unsafe { T::from_ptr(ptr as *mut _) }); let cloned = T::clone(&obj); Some(cloned)
91 } else {
92 None
93 }
94 }
95
96 #[must_use]
102 pub fn new_iunknown<T>(val: &impl ole_IUnknown) -> Self {
103 let mut cloned = val.clone();
104 let ptr = cloned.leak() as usize;
105 unsafe { Self::from_raw(co::VT::UNKNOWN, &ptr.to_ne_bytes()) }
106 }
107
108 #[must_use]
115 pub fn iunknown<T>(&self) -> Option<T>
116 where T: ole_IUnknown,
117 {
118 if self.vt() == co::VT::UNKNOWN {
119 let ptr = usize::from_ne_bytes(self.raw()[..8].try_into().unwrap());
120 let obj = ManuallyDrop::new(unsafe { T::from_ptr(ptr as *mut _) }); let cloned = T::clone(&obj); Some(cloned)
123 } else {
124 None
125 }
126 }
127}