Skip to content

Commit

Permalink
Implement get_type using enif_term_type
Browse files Browse the repository at this point in the history
  • Loading branch information
filmor committed Aug 23, 2023
1 parent 6e8349f commit 3f04c1a
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
43 changes: 32 additions & 11 deletions rustler/src/dynamic.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,62 @@
#[cfg(feature = "nif_version_2_15")]
use rustler_sys::ErlNifTermType;

use crate::wrapper::check;
use crate::Term;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TermType {
Atom,
Binary,
EmptyList,
Exception,
Fun,
List,
Map,
Number,
Integer,
Float,
Pid,
Port,
Ref,
Tuple,
Unknown,
}

#[cfg(feature = "nif_version_2_15")]
impl From<ErlNifTermType> for TermType {
fn from(term_type: ErlNifTermType) -> Self {
use ErlNifTermType::*;
use TermType::*;
match term_type {
ERL_NIF_TERM_TYPE_ATOM => Atom,
ERL_NIF_TERM_TYPE_BITSTRING => Binary,
ERL_NIF_TERM_TYPE_FLOAT => Float,
ERL_NIF_TERM_TYPE_FUN => Fun,
ERL_NIF_TERM_TYPE_INTEGER => Integer,
ERL_NIF_TERM_TYPE_LIST => List,
ERL_NIF_TERM_TYPE_MAP => Map,
ERL_NIF_TERM_TYPE_PID => Pid,
ERL_NIF_TERM_TYPE_PORT => Port,
ERL_NIF_TERM_TYPE_REFERENCE => Ref,
ERL_NIF_TERM_TYPE_TUPLE => Tuple,
_ => Unknown,
}
}
}

pub fn get_type(term: Term) -> TermType {
if term.is_atom() {
if cfg!(nif_version_2_15) {
term.get_erl_type().into()
} else if term.is_atom() {
TermType::Atom
} else if term.is_binary() {
TermType::Binary
} else if term.is_empty_list() {
TermType::EmptyList
} else if term.is_exception() {
TermType::Exception
} else if term.is_fun() {
TermType::Fun
} else if term.is_list() {
} else if term.is_list() || term.is_empty_list() {
TermType::List
} else if term.is_map() {
TermType::Map
} else if term.is_number() {
TermType::Number
TermType::Float
} else if term.is_pid() {
TermType::Pid
} else if term.is_port() {
Expand Down Expand Up @@ -68,7 +90,6 @@ impl<'a> Term<'a> {
impl_check!(is_atom);
impl_check!(is_binary);
impl_check!(is_empty_list);
impl_check!(is_exception);
impl_check!(is_fun);
impl_check!(is_list);
impl_check!(is_map);
Expand Down
5 changes: 5 additions & 0 deletions rustler/src/term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ impl<'a> Term<'a> {
as u32
}
}

#[cfg(feature = "nif_version_2_15")]
pub fn get_erl_type(&self) -> rustler_sys::ErlNifTermType {
unsafe { rustler_sys::enif_term_type(self.env.as_c_arg(), &self.as_c_arg()) }
}
}

impl<'a> PartialEq for Term<'a> {
Expand Down
2 changes: 1 addition & 1 deletion rustler/src/types/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub struct ListIterator<'a> {

impl<'a> ListIterator<'a> {
fn new(term: Term<'a>) -> Option<Self> {
if term.is_list() || term.is_empty_list() {
if term.is_list() {
let iter = ListIterator { term };
Some(iter)
} else {
Expand Down
1 change: 0 additions & 1 deletion rustler/src/wrapper/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ macro_rules! impl_check_fun {
impl_check_fun!(is_atom, rustler_sys::enif_is_atom);
impl_check_fun!(is_binary, rustler_sys::enif_is_binary);
impl_check_fun!(is_empty_list, rustler_sys::enif_is_empty_list);
impl_check_fun!(is_exception, rustler_sys::enif_is_exception);
impl_check_fun!(is_fun, rustler_sys::enif_is_fun);
impl_check_fun!(is_list, rustler_sys::enif_is_list);
impl_check_fun!(is_map, rustler_sys::enif_is_map);
Expand Down
1 change: 1 addition & 0 deletions rustler_sys/src/rustler_sys_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ pub enum ErlNifHash {
}

/// See [ErlNifTermType](http://www.erlang.org/doc/man/erl_nif.html#ErlNifTermType) in the Erlang docs.
#[cfg(feature = "nif_version_2_15")]
#[derive(Copy, Clone)]
#[repr(C)]
pub enum ErlNifTermType {
Expand Down

0 comments on commit 3f04c1a

Please sign in to comment.