use crate::wrapper::{c_uint, NIF_ENV, NIF_TERM};
use crate::Error;
use rustler_sys::ErlNifCharEncoding::ERL_NIF_LATIN1;
pub unsafe fn make_atom(env: NIF_ENV, name: &[u8]) -> NIF_TERM {
rustler_sys::enif_make_atom_len(env, name.as_ptr(), name.len())
}
pub unsafe fn make_existing_atom(env: NIF_ENV, name: &[u8]) -> Option<NIF_TERM> {
let mut atom_out: NIF_TERM = 0;
let success = rustler_sys::enif_make_existing_atom_len(
env,
name.as_ptr(),
name.len(),
&mut atom_out as *mut NIF_TERM,
ERL_NIF_LATIN1,
);
if success == 0 {
return None;
}
Some(atom_out)
}
pub unsafe fn get_atom(env: NIF_ENV, term: NIF_TERM) -> Result<String, Error> {
let mut len = 0;
let success = rustler_sys::enif_get_atom_length(env, term, &mut len, ERL_NIF_LATIN1);
if success == 0 {
return Err(Error::BadArg);
}
let mut bytes: Vec<u8> = Vec::with_capacity(len as usize + 1);
let nbytes = rustler_sys::enif_get_atom(env, term, bytes.as_mut_ptr(), len + 1, ERL_NIF_LATIN1);
assert!(nbytes as c_uint == len + 1);
bytes.set_len(len as usize);
let nonascii_count = bytes.iter().filter(|&&b| b >= 128).count();
if nonascii_count == 0 {
Ok(String::from_utf8_unchecked(bytes))
} else {
let mut out = String::with_capacity(bytes.len() + nonascii_count);
for b in bytes {
out.push(b as char);
}
Ok(out)
}
}