| 1 | use super::*; |
| 2 | use 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. |
| 8 | pub trait OutParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized |
| 9 | where |
| 10 | T: Type<T>, |
| 11 | { |
| 12 | #[doc (hidden)] |
| 13 | unsafe fn borrow_mut(&self) -> OutRef<'_, T>; |
| 14 | } |
| 15 | |
| 16 | impl<T> OutParam<T, CloneType> for &mut T |
| 17 | where |
| 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 | |
| 29 | impl<T> OutParam<T, CopyType> for &mut T |
| 30 | where |
| 31 | T: TypeKind<TypeKind = CopyType> + Clone + Default, |
| 32 | { |
| 33 | unsafe fn borrow_mut(&self) -> OutRef<'_, T> { |
| 34 | unsafe { transmute_copy(self) } |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | impl<T> OutParam<T, InterfaceType> for &mut Option<T> |
| 39 | where |
| 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 | |
| 51 | impl<T> OutParam<T> for Option<&mut T> |
| 52 | where |
| 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 | |