]>
Commit | Line | Data |
---|---|---|
353b0b11 FG |
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) => std::mem::transmute_copy(item), | |
14 | Self::Borrowed(borrowed) => std::mem::transmute_copy(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) => Ok(Param::Borrowed(from.abi())), | |
32 | None => Ok(Param::Borrowed(zeroed::<T>())), | |
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) => Param::Borrowed(item.abi()), | |
99 | None => Param::Borrowed(zeroed::<T>()), | |
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 | } |