safer_ffi_gen/
lib.rs

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/// Private definitions used by macros. These are always considered unstable and can have breaking
21/// changes between semver-compatible releases of this crate. Do not use.
22#[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}