1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use ::{NifTerm};
use ::wrapper::check;

pub enum TermType {
    Atom,
    Binary,
    EmptyList,
    Exception,
    Fun,
    List,
    Map,
    Pid,
    Port,
    Ref,
    Tuple,
    Unknown
}

pub fn get_type(term: NifTerm) -> TermType {
    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() {
        TermType::List
    } else if term.is_map() {
        TermType::Map
    } else if term.is_pid() {
        TermType::Pid
    } else if term.is_port() {
        TermType::Port
    } else if term.is_ref() {
        TermType::Ref
    } else if term.is_tuple() {
        TermType::Tuple
    } else {
        TermType::Unknown
    }
}

macro_rules! impl_check {
    ($check_fun:ident) => {
        pub fn $check_fun(self) -> bool {
            unsafe { check::$check_fun(self.get_env().as_c_arg(), self.as_c_arg()) }
        }
    }
}

/// ## Type checks
impl<'a> NifTerm<'a> {

    /// Returns an enum representing which type the term is.
    /// Note that using the individual `is_*` functions is more
    /// efficient for checking a single type.
    pub fn get_type(self) -> TermType {
        get_type(self)
    }

    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);
    impl_check!(is_pid);
    impl_check!(is_port);
    impl_check!(is_ref);
    impl_check!(is_tuple);

}