1#![allow(clippy::missing_safety_doc)]
16
17use crate::repr_c::ReprC;
18use crate::{ErrorCode, FfiResult};
19use std::fmt::{Debug, Display};
20use std::os::raw::c_void;
21use std::sync::mpsc::{self, Sender};
22use std::{fmt, ptr, slice};
23use unwrap::unwrap;
24
25pub struct UserData {
27 pub common: *mut c_void,
29 pub custom: *mut c_void,
31}
32
33impl Default for UserData {
34 fn default() -> Self {
35 let common: *const c_void = ptr::null();
36 let custom: *const c_void = ptr::null();
37
38 UserData {
39 common: common as *mut c_void,
40 custom: custom as *mut c_void,
41 }
42 }
43}
44
45pub fn user_data_as_void(ud: &UserData) -> *mut c_void {
47 let ptr: *const _ = ud;
48 ptr as *mut c_void
49}
50
51pub fn sender_as_user_data<T>(tx: &Sender<T>, ud: &mut UserData) -> *mut c_void {
54 let ptr: *const _ = tx;
55 ud.common = ptr as *mut c_void;
56 user_data_as_void(ud)
57}
58
59pub unsafe fn send_via_user_data<T>(user_data: *mut c_void, value: T)
61where
62 T: Send,
63{
64 let ud = user_data as *mut UserData;
65 let tx = (*ud).common as *mut Sender<T>;
66 unwrap!((*tx).send(value));
67}
68
69pub unsafe fn send_via_user_data_custom<T>(user_data: *mut c_void, value: T)
71where
72 T: Send,
73{
74 let ud = user_data as *mut UserData;
75 let tx = (*ud).custom as *mut Sender<T>;
76 unwrap!((*tx).send(value));
77}
78
79pub fn call_0<F>(f: F) -> Result<(), i32>
83where
84 F: FnOnce(*mut c_void, extern "C" fn(user_data: *mut c_void, result: *const FfiResult)),
85{
86 let mut ud = Default::default();
87 call_0_with_custom(&mut ud, f)
88}
89
90pub fn call_0_with_custom<F>(ud: &mut UserData, f: F) -> Result<(), i32>
95where
96 F: FnOnce(*mut c_void, extern "C" fn(user_data: *mut c_void, result: *const FfiResult)),
97{
98 let (tx, rx) = mpsc::channel::<i32>();
99 f(sender_as_user_data(&tx, ud), callback_0);
100
101 let error = unwrap!(rx.recv());
102 if error == 0 {
103 Ok(())
104 } else {
105 Err(error)
106 }
107}
108
109pub unsafe fn call_1<F, E: Debug, T>(f: F) -> Result<T, i32>
114where
115 F: FnOnce(*mut c_void, extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T::C)),
116 T: ReprC<Error = E>,
117{
118 let mut ud = Default::default();
119 call_1_with_custom(&mut ud, f)
120}
121
122pub fn call_1_with_custom<F, E: Debug, T>(ud: &mut UserData, f: F) -> Result<T, i32>
128where
129 F: FnOnce(*mut c_void, extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T::C)),
130 T: ReprC<Error = E>,
131{
132 let (tx, rx) = mpsc::channel::<SendWrapper<Result<T, i32>>>();
133 f(sender_as_user_data(&tx, ud), callback_1::<E, T>);
134 unwrap!(rx.recv()).0
135}
136
137pub unsafe fn call_2<F, E0, E1, T0, T1>(f: F) -> Result<(T0, T1), i32>
142where
143 F: FnOnce(
144 *mut c_void,
145 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T0::C, T1::C),
146 ),
147 E0: Debug,
148 E1: Debug,
149 T0: ReprC<Error = E0>,
150 T1: ReprC<Error = E1>,
151{
152 let mut ud = Default::default();
153 call_2_with_custom(&mut ud, f)
154}
155
156pub unsafe fn call_2_with_custom<F, E0, E1, T0, T1>(
162 ud: &mut UserData,
163 f: F,
164) -> Result<(T0, T1), i32>
165where
166 F: FnOnce(
167 *mut c_void,
168 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T0::C, T1::C),
169 ),
170 E0: Debug,
171 E1: Debug,
172 T0: ReprC<Error = E0>,
173 T1: ReprC<Error = E1>,
174{
175 let (tx, rx) = mpsc::channel::<SendWrapper<Result<(T0, T1), i32>>>();
176 f(sender_as_user_data(&tx, ud), callback_2::<E0, E1, T0, T1>);
177 unwrap!(rx.recv()).0
178}
179
180pub unsafe fn call_vec<F, E, T, U>(f: F) -> Result<Vec<T>, i32>
185where
186 F: FnOnce(
187 *mut c_void,
188 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T::C, usize),
189 ),
190 E: Debug,
191 T: ReprC<C = *const U, Error = E>,
192{
193 let mut ud = Default::default();
194 call_vec_with_custom(&mut ud, f)
195}
196
197pub unsafe fn call_vec_with_custom<F, E, T, U>(ud: &mut UserData, f: F) -> Result<Vec<T>, i32>
203where
204 F: FnOnce(
205 *mut c_void,
206 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, T::C, usize),
207 ),
208 E: Debug,
209 T: ReprC<C = *const U, Error = E>,
210{
211 let (tx, rx) = mpsc::channel::<SendWrapper<Result<Vec<T>, i32>>>();
212 f(sender_as_user_data(&tx, ud), callback_vec::<E, T, U>);
213 unwrap!(rx.recv()).0
214}
215
216pub unsafe fn call_vec_u8<F>(f: F) -> Result<Vec<u8>, i32>
219where
220 F: FnOnce(
221 *mut c_void,
222 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, *const u8, usize),
223 ),
224{
225 let mut ud = Default::default();
226 call_vec_u8_with_custom(&mut ud, f)
227}
228
229pub unsafe fn call_vec_u8_with_custom<F>(ud: &mut UserData, f: F) -> Result<Vec<u8>, i32>
234where
235 F: FnOnce(
236 *mut c_void,
237 extern "C" fn(user_data: *mut c_void, result: *const FfiResult, *const u8, usize),
238 ),
239{
240 let (tx, rx) = mpsc::channel::<Result<Vec<u8>, i32>>();
241 f(sender_as_user_data(&tx, ud), callback_vec_u8);
242 unwrap!(rx.recv())
243}
244
245extern "C" fn callback_0(user_data: *mut c_void, res: *const FfiResult) {
246 unsafe { send_via_user_data(user_data, (*res).error_code) }
247}
248
249extern "C" fn callback_1<E, T>(user_data: *mut c_void, res: *const FfiResult, arg: T::C)
250where
251 E: Debug,
252 T: ReprC<Error = E>,
253{
254 unsafe {
255 let result: Result<T, i32> = if (*res).error_code == 0 {
256 Ok(unwrap!(T::clone_from_repr_c(arg)))
257 } else {
258 Err((*res).error_code)
259 };
260 send_via_user_data(user_data, SendWrapper(result));
261 }
262}
263
264extern "C" fn callback_2<E0, E1, T0, T1>(
265 user_data: *mut c_void,
266 res: *const FfiResult,
267 arg0: T0::C,
268 arg1: T1::C,
269) where
270 E0: Debug,
271 E1: Debug,
272 T0: ReprC<Error = E0>,
273 T1: ReprC<Error = E1>,
274{
275 unsafe {
276 let result: Result<(T0, T1), i32> = if (*res).error_code == 0 {
277 Ok((
278 unwrap!(T0::clone_from_repr_c(arg0)),
279 unwrap!(T1::clone_from_repr_c(arg1)),
280 ))
281 } else {
282 Err((*res).error_code)
283 };
284 send_via_user_data(user_data, SendWrapper(result))
285 }
286}
287
288extern "C" fn callback_vec<E, T, U>(
289 user_data: *mut c_void,
290 res: *const FfiResult,
291 array: *const U,
292 size: usize,
293) where
294 E: Debug,
295 T: ReprC<C = *const U, Error = E>,
296{
297 unsafe {
298 let result: Result<Vec<T>, i32> = if (*res).error_code == 0 {
299 let slice_ffi = slice::from_raw_parts(array, size);
300 let mut vec = Vec::with_capacity(slice_ffi.len());
301 for elt in slice_ffi {
302 vec.push(unwrap!(T::clone_from_repr_c(elt)));
303 }
304 Ok(vec)
305 } else {
306 Err((*res).error_code)
307 };
308
309 send_via_user_data(user_data, SendWrapper(result))
310 }
311}
312
313extern "C" fn callback_vec_u8(
314 user_data: *mut c_void,
315 res: *const FfiResult,
316 ptr: *const u8,
317 len: usize,
318) {
319 unsafe {
320 let result = if (*res).error_code == 0 {
321 Ok(slice::from_raw_parts(ptr, len).to_vec())
322 } else {
323 Err((*res).error_code)
324 };
325
326 send_via_user_data(user_data, result)
327 }
328}
329
330pub struct SendWrapper<T>(pub T);
333unsafe impl<T> Send for SendWrapper<T> {}
334
335#[derive(Debug)]
337pub enum TestError {
338 FromStr(String),
340 Test,
342}
343
344impl<'a> From<&'a str> for TestError {
345 fn from(s: &'a str) -> Self {
346 TestError::FromStr(s.into())
347 }
348}
349
350impl ErrorCode for TestError {
351 fn error_code(&self) -> i32 {
352 use TestError::*;
353
354 match *self {
355 Test => -1,
356 FromStr(_) => -2,
357 }
358 }
359}
360
361impl Display for TestError {
362 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
363 use TestError::*;
364
365 match self {
366 Test => write!(f, "Test Error"),
367 FromStr(s) => write!(f, "{}", s),
368 }
369 }
370}