use super::nif_interface;
use super::nif_interface::{c_uint, NIF_ENV, NIF_TERM};
use {Error, NifResult};
pub unsafe fn make_atom(env: NIF_ENV, name: &[u8]) -> NIF_TERM {
nif_interface::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 = nif_interface::enif_make_existing_atom_len(
env,
name.as_ptr(),
name.len(),
&mut atom_out as *mut NIF_TERM,
);
if success == 0 {
return None;
}
Some(atom_out)
}
pub unsafe fn get_atom(env: NIF_ENV, term: NIF_TERM) -> NifResult<String> {
let mut len = 0;
let success = nif_interface::enif_get_atom_length_latin1(env, term, &mut len);
if success == 0 {
return Err(Error::BadArg);
}
let mut bytes: Vec<u8> = Vec::with_capacity(len as usize + 1);
let nbytes = nif_interface::enif_get_atom_latin1(env, term, bytes.as_mut_ptr(), len + 1);
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)
}
}