1use super::*;
2use core::mem::transmute_copy;
3use core::mem::zeroed;
4
5/// Provides automatic parameter conversion in cases where the Windows API expects implicit conversion support.
6///
7/// There is no need to implement this trait. Blanket implementations are provided for all applicable Windows types.
8pub trait Param<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized
9where
10 T: Type<T>,
11{
12 #[doc(hidden)]
13 unsafe fn param(self) -> ParamValue<T>;
14}
15
16impl<T> Param<T> for Option<&T>
17where
18 T: Type<T>,
19{
20 unsafe fn param(self) -> ParamValue<T> {
21 unsafe {
22 ParamValue::Borrowed(match self {
23 Some(item: &T) => transmute_copy(src:item),
24 None => zeroed(),
25 })
26 }
27 }
28}
29
30impl<T> Param<T> for InterfaceRef<'_, T>
31where
32 T: Type<T>,
33{
34 unsafe fn param(self) -> ParamValue<T> {
35 unsafe { ParamValue::Borrowed(transmute_copy(&self)) }
36 }
37}
38
39impl<T, U> Param<T, InterfaceType> for &U
40where
41 T: TypeKind<TypeKind = InterfaceType> + Clone,
42 T: Interface,
43 U: Interface,
44 U: imp::CanInto<T>,
45{
46 unsafe fn param(self) -> ParamValue<T> {
47 unsafe {
48 if U::QUERY {
49 self.cast()
50 .map_or(default:ParamValue::Borrowed(zeroed()), |ok: T| ParamValue::Owned(ok))
51 } else {
52 ParamValue::Borrowed(transmute_copy(self))
53 }
54 }
55 }
56}
57
58impl<T> Param<T, CloneType> for &T
59where
60 T: TypeKind<TypeKind = CloneType> + Clone,
61{
62 unsafe fn param(self) -> ParamValue<T> {
63 unsafe { ParamValue::Borrowed(transmute_copy(self)) }
64 }
65}
66
67impl<T, U> Param<T, CopyType> for U
68where
69 T: TypeKind<TypeKind = CopyType> + Clone,
70 U: TypeKind<TypeKind = CopyType> + Clone,
71 U: imp::CanInto<T>,
72{
73 unsafe fn param(self) -> ParamValue<T> {
74 unsafe { ParamValue::Owned(transmute_copy(&self)) }
75 }
76}
77