1
#![forbid(unsafe_code)]
2

            
3
use std::fmt;
4

            
5
use delegate::delegate;
6

            
7
use merc_macros::merc_derive_terms;
8
use merc_macros::merc_term;
9

            
10
use crate::ATerm;
11
use crate::ATermArgs;
12
use crate::ATermIndex;
13
use crate::ATermRef;
14
use crate::Markable;
15
use crate::Symb;
16
use crate::SymbolRef;
17
use crate::Term;
18
use crate::TermIterator;
19
use crate::Transmutable;
20
use crate::storage::Marker;
21
use crate::storage::THREAD_TERM_POOL;
22

            
23
/// Returns true if the term is an [ATermInt] term.
24
683488531
pub fn is_int_term<'a, 'b>(t: &'b impl Term<'a, 'b>) -> bool {
25
683488531
    THREAD_TERM_POOL.with_borrow(|tp| *tp.int_symbol() == t.get_head_symbol())
26
683488531
}
27

            
28
/// Returns true if the symbol is an integer.
29
195265
pub fn is_int_symbol<'a, 'b>(f: &'b impl Symb<'a, 'b>) -> bool {
30
195265
    THREAD_TERM_POOL.with_borrow(|tp| *tp.int_symbol() == f.copy())
31
195265
}
32

            
33
#[merc_derive_terms]
34
mod inner {
35
    use merc_macros::merc_ignore;
36

            
37
    use super::*;
38

            
39
    /// This is a wrapper around the [ATerm] type that stores a single `u64` using an annotation.
40
    #[merc_term(is_int_term)]
41
    pub struct ATermInt {
42
        term: ATerm,
43
    }
44

            
45
    impl ATermInt {
46
        #[merc_ignore]
47
3741624
        pub fn new(value: usize) -> ATermInt {
48
3741624
            THREAD_TERM_POOL.with_borrow(|tp| ATermInt {
49
3741624
                term: tp.create_int(value),
50
3741624
            })
51
3741624
        }
52

            
53
        /// Returns the value of the integer term.
54
3741434
        pub fn value(&self) -> usize {
55
3741434
            self.term.annotation().unwrap()
56
3741434
        }
57
    }
58
}
59

            
60
impl fmt::Display for ATermInt {
61
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62
        write!(f, "{}", self.value())
63
    }
64
}
65

            
66
impl fmt::Display for ATermIntRef<'_> {
67
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68
        write!(f, "{}", self.value())
69
    }
70
}
71

            
72
pub use inner::*;
73

            
74
#[cfg(test)]
75
mod tests {
76
    use merc_utilities::test_logger;
77

            
78
    use super::*;
79

            
80
    #[test]
81
1
    fn test_int_term() {
82
1
        let _ = test_logger();
83

            
84
1
        let int_term = ATermInt::new(42);
85
1
        assert_eq!(int_term.value(), 42);
86
1
        assert!(is_int_term(&int_term));
87
1
    }
88
}