1use super::*;
2
3#[doc(hidden)]
4pub trait TypeKind {
5 type TypeKind;
6}
7
8#[doc(hidden)]
9pub struct InterfaceType;
10
11#[doc(hidden)]
12pub struct CloneType;
13
14#[doc(hidden)]
15pub struct CopyType;
16
17#[doc(hidden)]
18pub trait Type<T: TypeKind, C = <T as TypeKind>::TypeKind>: TypeKind + Sized + Clone {
19 type Abi;
20 type Default;
21
22 fn is_null(abi: &Self::Abi) -> bool;
23 unsafe fn assume_init_ref(abi: &Self::Abi) -> &Self;
24 unsafe fn from_abi(abi: Self::Abi) -> Result<Self>;
25 fn from_default(default: &Self::Default) -> Result<Self>;
26}
27
28impl<T> Type<T, InterfaceType> for T
29where
30 T: TypeKind<TypeKind = InterfaceType> + Clone,
31{
32 type Abi = *mut core::ffi::c_void;
33 type Default = Option<Self>;
34
35 fn is_null(abi: &Self::Abi) -> bool {
36 abi.is_null()
37 }
38
39 unsafe fn assume_init_ref(abi: &Self::Abi) -> &Self {
40 unsafe { core::mem::transmute::<&*mut core::ffi::c_void, &T>(abi) }
41 }
42
43 unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
44 unsafe {
45 if !abi.is_null() {
46 Ok(core::mem::transmute_copy(&abi))
47 } else {
48 Err(Error::empty())
49 }
50 }
51 }
52
53 fn from_default(default: &Self::Default) -> Result<Self> {
54 default.as_ref().cloned().ok_or(Error::empty())
55 }
56}
57
58impl<T> Type<T, CloneType> for T
59where
60 T: TypeKind<TypeKind = CloneType> + Clone,
61{
62 type Abi = core::mem::MaybeUninit<Self>;
63 type Default = Self;
64
65 fn is_null(_: &Self::Abi) -> bool {
66 false
67 }
68
69 unsafe fn assume_init_ref(abi: &Self::Abi) -> &Self {
70 unsafe { abi.assume_init_ref() }
71 }
72
73 unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
74 unsafe { Ok(abi.assume_init()) }
75 }
76
77 fn from_default(default: &Self::Default) -> Result<Self> {
78 Ok(default.clone())
79 }
80}
81
82impl<T> Type<T, CopyType> for T
83where
84 T: TypeKind<TypeKind = CopyType> + Clone,
85{
86 type Abi = Self;
87 type Default = Self;
88
89 fn is_null(_: &Self::Abi) -> bool {
90 false
91 }
92
93 unsafe fn assume_init_ref(abi: &Self::Abi) -> &Self {
94 abi
95 }
96
97 unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
98 Ok(abi)
99 }
100
101 fn from_default(default: &Self) -> Result<Self> {
102 Ok(default.clone())
103 }
104}
105
106impl<T: Interface> TypeKind for T {
107 type TypeKind = InterfaceType;
108}
109
110impl<T> TypeKind for *mut T {
111 type TypeKind = CopyType;
112}
113
114macro_rules! primitives {
115 ($($t:ty),+) => {
116 $(
117 impl TypeKind for $t {
118 type TypeKind = CopyType;
119 }
120 )*
121 };
122}
123
124primitives!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, usize, isize);
125
126#[doc(hidden)]
127pub type AbiType<T> = <T as Type<T>>::Abi;
128