1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use super::{ErrorCode, FfiResult};
use super::callback::{Callback, CallbackArgs};
use std::fmt::{Debug, Display};
use std::os::raw::c_void;
use std::panic::{self, AssertUnwindSafe};
fn catch_unwind_result<'a, F, T, E>(f: F) -> Result<T, E>
where
F: FnOnce() -> Result<T, E>,
E: Debug + From<&'a str>,
{
match panic::catch_unwind(AssertUnwindSafe(f)) {
Err(_) => Err(E::from("panic")),
Ok(result) => result,
}
}
pub fn catch_unwind_error_code<'a, F, E>(f: F) -> i32
where
F: FnOnce() -> Result<(), E>,
E: Debug + ErrorCode + From<&'a str>,
{
ffi_result_code!(catch_unwind_result(f))
}
pub fn catch_unwind_cb<'a, U, C, F, E>(user_data: U, cb: C, f: F)
where
U: Into<*mut c_void>,
C: Callback + Copy,
F: FnOnce() -> Result<(), E>,
E: Debug + Display + ErrorCode + From<&'a str>,
{
if let Err(err) = catch_unwind_result(f) {
let (error_code, description) = ffi_result!(Err::<(), E>(err));
cb.call(
user_data.into(),
FfiResult {
error_code,
description: description.as_ptr(),
},
CallbackArgs::default(),
);
}
}