use std::os::raw::c_int;
use std::panic::AssertUnwindSafe;
use wolfram_library_link::macro_utils::call_and_catch_as_expr;
use wolfram_library_link::sys::{self, MArgument};
use wolfram_library_link::NativeFunction;
pub unsafe fn call_native_wolfram_library_function<'a, F: NativeFunction<'a>>(
lib_data: sys::WolframLibraryData,
args: *mut MArgument,
argc: sys::mint,
res: MArgument,
func: F,
) -> c_int {
if wolfram_library_link::initialize(lib_data).is_err() {
return wolfram_library_link::FAILED_TO_INIT;
}
let argc = match usize::try_from(argc) {
Ok(argc) => argc,
Err(_) => return wolfram_library_link::sys::LIBRARY_FUNCTION_ERROR as c_int,
};
let args: &[MArgument] = std::slice::from_raw_parts(args, argc);
if call_and_catch_as_expr(AssertUnwindSafe(move || func.call(args, res))).is_err() {
return wolfram_library_link::FAILED_WITH_PANIC;
}
sys::LIBRARY_NO_ERROR as c_int
}
pub unsafe fn init_with_user_function(
lib: sys::WolframLibraryData,
user_init_func: fn(),
) -> c_int {
if wolfram_library_link::initialize(lib).is_err() {
return wolfram_library_link::FAILED_TO_INIT;
}
if call_and_catch_as_expr(user_init_func).is_err() {
wolfram_library_link::FAILED_WITH_PANIC
} else {
sys::LIBRARY_NO_ERROR as c_int
}
}