1use super::*;
2use core::mem::{take, transmute_copy, zeroed};
3
4/// Provides automatic parameter conversion in cases where the Windows API expects implicit conversion support.
5///
6/// This is a mutable version of [Param] meant to support out parameters.
7/// There is no need to implement this trait. Blanket implementations are provided for all applicable Windows types.
8pub trait OutParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized
9where
10 T: Type<T>,
11{
12 #[doc(hidden)]
13 unsafe fn borrow_mut(&self) -> OutRef<'_, T>;
14}
15
16impl<T> OutParam<T, CloneType> for &mut T
17where
18 T: TypeKind<TypeKind = CloneType> + Clone + Default,
19{
20 unsafe fn borrow_mut(&self) -> OutRef<'_, T> {
21 unsafe {
22 let this: &mut T = transmute_copy(self);
23 take(dest:this);
24 transmute_copy(self)
25 }
26 }
27}
28
29impl<T> OutParam<T, CopyType> for &mut T
30where
31 T: TypeKind<TypeKind = CopyType> + Clone + Default,
32{
33 unsafe fn borrow_mut(&self) -> OutRef<'_, T> {
34 unsafe { transmute_copy(self) }
35 }
36}
37
38impl<T> OutParam<T, InterfaceType> for &mut Option<T>
39where
40 T: TypeKind<TypeKind = InterfaceType> + Clone,
41{
42 unsafe fn borrow_mut(&self) -> OutRef<'_, T> {
43 unsafe {
44 let this: &mut Option<T> = transmute_copy(self);
45 take(dest:this);
46 transmute_copy(self)
47 }
48 }
49}
50
51impl<T> OutParam<T> for Option<&mut T>
52where
53 T: Type<T>,
54{
55 unsafe fn borrow_mut(&self) -> OutRef<'_, T> {
56 unsafe {
57 match self {
58 Some(this: &&mut T) => transmute_copy(src:this),
59 None => zeroed(),
60 }
61 }
62 }
63}
64