use ::{NifEnv, NifTerm};
use std::panic::catch_unwind;
use ::types::atom::NifAtom;
use ::wrapper::exception;
use ::NifResult;
pub use ::wrapper::nif_interface::{
c_int, c_void, DEF_NIF_ENTRY, DEF_NIF_FUNC,
NIF_ENV, NIF_TERM, NIF_MAJOR_VERSION, NIF_MINOR_VERSION,
MUTABLE_NIF_RESOURCE_HANDLE };
pub unsafe fn handle_nif_call(function: for<'a> fn(NifEnv<'a>, &[NifTerm<'a>]) -> NifResult<NifTerm<'a>>,
_arity: usize, r_env: NIF_ENV,
argc: c_int, argv: *const NIF_TERM) -> NIF_TERM {
let env_lifetime = ();
let env = NifEnv::new(&env_lifetime, r_env);
let terms = ::std::slice::from_raw_parts(argv, argc as usize).iter()
.map(|x| NifTerm::new(env, *x)).collect::<Vec<NifTerm>>();
let result: ::std::thread::Result<NIF_TERM> = catch_unwind(|| {
match function(env, &terms) {
Ok(ret) => ret.as_c_arg(),
Err(err) => err.encode(env).as_c_arg(),
}
});
match result {
Ok(res) => res,
Err(_err) =>
exception::raise_exception(
env.as_c_arg(),
NifAtom::from_bytes(env, b"nif_panic").ok().unwrap().as_c_arg()),
}
}
pub unsafe fn handle_nif_init_call(function: Option<for<'a> fn(NifEnv<'a>, NifTerm<'a>) -> bool>,
r_env: NIF_ENV,
load_info: NIF_TERM) -> c_int {
let env_lifetime = ();
let env = NifEnv::new(&env_lifetime, r_env);
let term = NifTerm::new(env, load_info);
if let Some(inner) = function {
if inner(env, term) { 0 } else { 1 }
} else {
0
}
}