use std::ffi::c_int;
pub use crate::codec::{CodecError, Decoder, Encoder};
pub use crate::priv_data::{discard_priv_data, free_priv_data, install_priv_data, PrivData};
#[cfg(feature = "raw")]
pub use crate::priv_data::{old_user_priv_field, user_priv_field};
pub use crate::resource::{register, register_tagged, ResourceFlags};
pub use crate::types::{Atom, CallEnv, CallbackEnv, DeinitEnv, InitEnv, TypedTerm};
use crate::types::{AnyTerm, Env, Term, THE_NON_VALUE};
pub mod ffi {
pub use enif_ffi::{
DIRTY_JOB_CPU_BOUND, DIRTY_JOB_IO_BOUND, Entry, Env, MAJOR_VERSION, MIN_ERTS_VERSION,
MINOR_VERSION, ResourceTypeInit, Term, VM_VARIANT,
};
}
pub const NIF_ENTRY_OPTIONS: u32 = 1;
pub const LOAD_OK: c_int = 0;
pub const LOAD_FAILED_USER_FALSE: c_int = 1;
pub const LOAD_FAILED_PANIC: c_int = 2;
pub const LOAD_FAILED_DECODE: c_int = 3;
pub struct NifMeta {
pub name: &'static [u8],
pub arity: u32,
pub raw_fptr:
unsafe extern "C" fn(*mut enif_ffi::Env, c_int, *const enif_ffi::Term) -> enif_ffi::Term,
pub flags: u32,
}
impl NifMeta {
pub fn to_nif_func(&self) -> enif_ffi::Func {
enif_ffi::Func {
name: self.name.as_ptr() as *const std::ffi::c_char,
arity: self.arity as std::ffi::c_uint,
fptr: self.raw_fptr,
flags: self.flags as std::ffi::c_uint,
}
}
}
pub fn decode_arg<'id, T: Decoder<'id>>(
env: impl Env<'id>,
raw: enif_ffi::Term,
) -> Result<T, CodecError> {
T::decode(AnyTerm::wrap(raw, env), env)
}
pub fn encode_result<'id, T: Encoder<'id>>(val: &T, env: CallEnv<'id>) -> enif_ffi::Term {
match val.encode(env) {
Ok(term) => Term::raw_term(term),
Err(_) => badret_word(env),
}
}
pub fn badarg_word(env: CallEnv<'_>) -> enif_ffi::Term {
let _ = env.badarg::<()>();
THE_NON_VALUE
}
pub fn badret_word(env: CallEnv<'_>) -> enif_ffi::Term {
match Atom::intern(env, "badret") {
Ok(atom) => {
let _ = env.raise::<()>(atom);
THE_NON_VALUE
}
Err(_) => badarg_word(env),
}
}
pub fn raise_word(env: CallEnv<'_>, reason: enif_ffi::Term) -> enif_ffi::Term {
let _ = env.raise::<()>(AnyTerm::wrap(reason, env));
THE_NON_VALUE
}