1use super::*;
2
3#[doc(hidden)]
4pub enum Param<T: Type<T>> {
5 Owned(T),
6 Borrowed(T::Abi),
7}
8
9impl<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)]
21pub trait TryIntoParam<T: Type<T>> {
22 fn try_into_param(self) -> Result<Param<T>>;
23}
24
25impl<T> TryIntoParam<T> for Option<&T>
26where
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
37impl<T, U> TryIntoParam<T> for &U
38where
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)]
53pub trait CanTryInto<T>: ComInterface
54where
55 T: ComInterface,
56{
57 const CAN_INTO: bool = false;
58}
59
60impl<T, U> CanTryInto<T> for U
61where
62 T: ComInterface,
63 U: ComInterface,
64 U: CanInto<T>,
65{
66 const CAN_INTO: bool = true;
67}
68
69#[doc(hidden)]
70pub trait CanInto<T>: Sized
71where
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}
82impl<T> CanInto<T> for T where T: Clone {}
83
84#[doc(hidden)]
85pub trait IntoParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized
86where
87 T: Type<T>,
88{
89 fn into_param(self) -> Param<T>;
90}
91
92impl<T> IntoParam<T> for Option<&T>
93where
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
104impl<T, U> IntoParam<T, ReferenceType> for &U
105where
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
115impl<T> IntoParam<T, ValueType> for &T
116where
117 T: TypeKind<TypeKind = ValueType> + Clone,
118{
119 fn into_param(self) -> Param<T> {
120 Param::Borrowed(self.abi())
121 }
122}
123
124impl<T, U> IntoParam<T, CopyType> for U
125where
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