1#![cfg_attr(not(feature = "std"), no_std)]
2
3extern crate alloc;
4
5use alloc::{boxed::Box, string::String, vec, vec::Vec};
6use safer_ffi::layout::ReprC;
7
8pub use safer_ffi;
9pub use safer_ffi_gen_macro::*;
10
11mod async_util;
12mod error;
13mod opaque;
14
15pub use async_util::*;
16
17#[cfg(feature = "std")]
18pub use error::last_error;
19
20#[doc(hidden)]
23pub mod private {
24 #[cfg(feature = "std")]
25 pub use crate::error::{set_last_error, WrapDebug, WrapError, WrapNotDebug, WrapNotError};
26
27 pub use crate::{
28 error::{WrapIntoInt, WrapNotIntoInt},
29 opaque::OpaqueLayout,
30 };
31}
32
33pub trait FfiType {
34 type Safe;
35
36 fn into_safe(self) -> Self::Safe;
37 fn from_safe(x: Self::Safe) -> Self;
38}
39
40macro_rules! impl_ffi_type_as_identity {
41 ($ty:ty) => {
42 impl FfiType for $ty {
43 type Safe = $ty;
44
45 fn into_safe(self) -> $ty {
46 self
47 }
48
49 fn from_safe(x: $ty) -> $ty {
50 x
51 }
52 }
53 };
54}
55
56impl_ffi_type_as_identity!(i8);
57impl_ffi_type_as_identity!(u8);
58impl_ffi_type_as_identity!(i16);
59impl_ffi_type_as_identity!(u16);
60impl_ffi_type_as_identity!(i32);
61impl_ffi_type_as_identity!(u32);
62impl_ffi_type_as_identity!(i64);
63impl_ffi_type_as_identity!(u64);
64impl_ffi_type_as_identity!(isize);
65impl_ffi_type_as_identity!(usize);
66impl_ffi_type_as_identity!(bool);
67impl_ffi_type_as_identity!(());
68
69impl<'a> FfiType for &'a str {
70 type Safe = safer_ffi::string::str_ref<'a>;
71
72 fn into_safe(self) -> Self::Safe {
73 self.into()
74 }
75
76 fn from_safe(x: Self::Safe) -> Self {
77 x.as_str()
78 }
79}
80
81impl FfiType for String {
82 type Safe = safer_ffi::String;
83
84 fn into_safe(self) -> Self::Safe {
85 self.into()
86 }
87
88 fn from_safe(x: Self::Safe) -> Self {
89 x.into()
90 }
91}
92
93impl<'a, T: ReprC + 'a> FfiType for &'a [T] {
94 type Safe = safer_ffi::slice::slice_ref<'a, T>;
95
96 fn into_safe(self) -> Self::Safe {
97 self.into()
98 }
99
100 fn from_safe(x: Self::Safe) -> Self {
101 x.as_slice()
102 }
103}
104
105impl<'a, T: ReprC + 'a> FfiType for &'a mut [T] {
106 type Safe = safer_ffi::slice::slice_mut<'a, T>;
107
108 fn into_safe(self) -> Self::Safe {
109 self.into()
110 }
111
112 fn from_safe(x: Self::Safe) -> Self {
113 x.as_slice()
114 }
115}
116
117impl<T: ReprC> FfiType for Vec<T> {
118 type Safe = safer_ffi::Vec<T>;
119
120 fn into_safe(self) -> Self::Safe {
121 self.into()
122 }
123
124 fn from_safe(x: Self::Safe) -> Self {
125 x.into()
126 }
127}
128
129impl<T: ReprC> FfiType for Box<T> {
130 type Safe = safer_ffi::boxed::Box<T>;
131
132 fn into_safe(self) -> Self::Safe {
133 self.into()
134 }
135
136 fn from_safe(x: Self::Safe) -> Self {
137 x.into()
138 }
139}
140
141impl<T> FfiType for Option<T>
142where
143 T: FfiType,
144 Option<T::Safe>: ReprC,
145{
146 type Safe = Option<T::Safe>;
147
148 fn into_safe(self) -> Self::Safe {
149 self.map(T::into_safe)
150 }
151
152 fn from_safe(x: Self::Safe) -> Self {
153 x.map(T::from_safe)
154 }
155}
156
157impl<'a, T: ReprC> FfiType for &'a T {
158 type Safe = &'a T;
159
160 fn into_safe(self) -> Self::Safe {
161 self
162 }
163
164 fn from_safe(x: Self::Safe) -> Self {
165 x
166 }
167}
168
169impl<'a, T: ReprC> FfiType for &'a mut T {
170 type Safe = &'a mut T;
171
172 fn into_safe(self) -> Self::Safe {
173 self
174 }
175
176 fn from_safe(x: Self::Safe) -> Self {
177 x
178 }
179}
180
181impl<T: FfiType, U: FfiType> FfiType for (T, U) {
182 type Safe = safer_ffi::Tuple2<T::Safe, U::Safe>;
183
184 fn into_safe(self) -> Self::Safe {
185 safer_ffi::Tuple2 {
186 _0: self.0.into_safe(),
187 _1: self.1.into_safe(),
188 }
189 }
190
191 fn from_safe(x: Self::Safe) -> Self {
192 (T::from_safe(x._0), U::from_safe(x._1))
193 }
194}
195
196impl<const N: usize, T: ReprC> FfiType for [T; N] {
197 type Safe = Self;
198
199 fn into_safe(self) -> Self::Safe {
200 self
201 }
202
203 fn from_safe(x: Self::Safe) -> Self {
204 x
205 }
206}
207
208#[safer_ffi::ffi_export]
209pub fn vec_u8_free(_v: safer_ffi::vec::Vec<u8>) {}
210
211#[safer_ffi::ffi_export]
212pub fn vec_u8_new(length: usize) -> safer_ffi::vec::Vec<u8> {
213 vec![0; length].into()
214}
215
216#[safer_ffi::ffi_export]
217pub fn vec_u8_from_slice(bytes: safer_ffi::slice::slice_ref<'_, u8>) -> safer_ffi::vec::Vec<u8> {
218 bytes.to_vec().into()
219}