1 | use super::*; |
2 | |
3 | #[doc (hidden)] |
4 | pub enum Param<T: Type<T>> { |
5 | Owned(T), |
6 | Borrowed(T::Abi), |
7 | } |
8 | |
9 | impl<T: Type<T>> Param<T> { |
10 | pub fn abi(&self) -> T::Abi { |
11 | unsafe { |
12 | match self { |
13 | Self::Owned(item: &T) => std::mem::transmute_copy(src:item), |
14 | Self::Borrowed(borrowed: &::TypeKind>>::Abi) => std::mem::transmute_copy(src:borrowed), |
15 | } |
16 | } |
17 | } |
18 | } |
19 | |
20 | #[doc (hidden)] |
21 | pub trait TryIntoParam<T: Type<T>> { |
22 | fn try_into_param(self) -> Result<Param<T>>; |
23 | } |
24 | |
25 | impl<T> TryIntoParam<T> for Option<&T> |
26 | where |
27 | T: ComInterface, |
28 | { |
29 | fn try_into_param(self) -> Result<Param<T>> { |
30 | match self { |
31 | Some(from: &T) => Ok(Param::Borrowed(from.abi())), |
32 | None => Ok(Param::Borrowed(unsafe { std::mem::zeroed() })), |
33 | } |
34 | } |
35 | } |
36 | |
37 | impl<T, U> TryIntoParam<T> for &U |
38 | where |
39 | T: ComInterface, |
40 | U: ComInterface, |
41 | U: CanTryInto<T>, |
42 | { |
43 | fn try_into_param(self) -> Result<Param<T>> { |
44 | if U::CAN_INTO { |
45 | Ok(Param::Borrowed(self.abi())) |
46 | } else { |
47 | Ok(Param::Owned(self.cast()?)) |
48 | } |
49 | } |
50 | } |
51 | |
52 | #[doc (hidden)] |
53 | pub trait CanTryInto<T>: ComInterface |
54 | where |
55 | T: ComInterface, |
56 | { |
57 | const CAN_INTO: bool = false; |
58 | } |
59 | |
60 | impl<T, U> CanTryInto<T> for U |
61 | where |
62 | T: ComInterface, |
63 | U: ComInterface, |
64 | U: CanInto<T>, |
65 | { |
66 | const CAN_INTO: bool = true; |
67 | } |
68 | |
69 | #[doc (hidden)] |
70 | pub trait CanInto<T>: Sized |
71 | where |
72 | T: Clone, |
73 | { |
74 | fn can_into(&self) -> &T { |
75 | unsafe { std::mem::transmute(self) } |
76 | } |
77 | |
78 | fn can_clone_into(&self) -> T { |
79 | self.can_into().clone() |
80 | } |
81 | } |
82 | impl<T> CanInto<T> for T where T: Clone {} |
83 | |
84 | #[doc (hidden)] |
85 | pub trait IntoParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized |
86 | where |
87 | T: Type<T>, |
88 | { |
89 | fn into_param(self) -> Param<T>; |
90 | } |
91 | |
92 | impl<T> IntoParam<T> for Option<&T> |
93 | where |
94 | T: Type<T>, |
95 | { |
96 | fn into_param(self) -> Param<T> { |
97 | match self { |
98 | Some(item: &T) => Param::Borrowed(item.abi()), |
99 | None => Param::Borrowed(unsafe { std::mem::zeroed() }), |
100 | } |
101 | } |
102 | } |
103 | |
104 | impl<T, U> IntoParam<T, ReferenceType> for &U |
105 | where |
106 | T: TypeKind<TypeKind = ReferenceType> + Clone, |
107 | U: TypeKind<TypeKind = ReferenceType> + Clone, |
108 | U: CanInto<T>, |
109 | { |
110 | fn into_param(self) -> Param<T> { |
111 | Param::Borrowed(self.abi()) |
112 | } |
113 | } |
114 | |
115 | impl<T> IntoParam<T, ValueType> for &T |
116 | where |
117 | T: TypeKind<TypeKind = ValueType> + Clone, |
118 | { |
119 | fn into_param(self) -> Param<T> { |
120 | Param::Borrowed(self.abi()) |
121 | } |
122 | } |
123 | |
124 | impl<T, U> IntoParam<T, CopyType> for U |
125 | where |
126 | T: TypeKind<TypeKind = CopyType> + Clone, |
127 | U: TypeKind<TypeKind = CopyType> + Clone, |
128 | U: CanInto<T>, |
129 | { |
130 | fn into_param(self) -> Param<T> { |
131 | unsafe { Param::Owned(std::mem::transmute_copy(&self)) } |
132 | } |
133 | } |
134 | |