1
use std::borrow::Borrow;
2
use std::marker::PhantomData;
3

            
4
use std::cmp::Ordering;
5
use std::fmt;
6
use std::hash::Hash;
7
use std::hash::Hasher;
8
use std::ops::Deref;
9

            
10
use mcrl2_sys::atermpp::ffi::{self};
11

            
12
#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
13
pub struct SymbolRef<'a> {
14
    symbol: *const ffi::_function_symbol,
15
    marker: PhantomData<&'a ()>,
16
}
17

            
18
/// A Symbol references to an aterm function symbol, which has a name and an arity.
19
impl<'a> SymbolRef<'a> {
20
686513084
    fn new(symbol: *const ffi::_function_symbol) -> SymbolRef<'a> {
21
686513084
        SymbolRef {
22
686513084
            symbol,
23
686513084
            marker: PhantomData,
24
686513084
        }
25
686513084
    }
26

            
27
668556
    pub fn protect(&self) -> Symbol {
28
668556
        Symbol::new(self.symbol)
29
668556
    }
30

            
31
685791712
    pub fn copy(&self) -> SymbolRef<'_> {
32
685791712
        SymbolRef::new(self.symbol)
33
685791712
    }
34
}
35

            
36
impl SymbolRef<'_> {
37
    /// Obtain the symbol's name
38
300321
    pub fn name(&self) -> &str {
39
300321
        unsafe { ffi::get_function_symbol_name(self.symbol) }
40
300321
    }
41

            
42
    /// Obtain the symbol's arity
43
14740040467
    pub fn arity(&self) -> usize {
44
14740040467
        unsafe { ffi::get_function_symbol_arity(self.symbol) }
45
14740040467
    }
46

            
47
    /// Returns the index of the function symbol
48
50357414
    pub fn address(&self) -> *const ffi::_function_symbol {
49
50357414
        self.symbol
50
50357414
    }
51
}
52

            
53
impl fmt::Display for SymbolRef<'_> {
54
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55
        write!(f, "{}", self.name())
56
    }
57
}
58

            
59
impl fmt::Debug for SymbolRef<'_> {
60
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61
        write!(f, "{}:{} [{}]", self.name(), self.arity(), self.address() as usize,)
62
    }
63
}
64

            
65
impl From<*const ffi::_function_symbol> for SymbolRef<'_> {
66
14005997586
    fn from(symbol: *const ffi::_function_symbol) -> Self {
67
14005997586
        SymbolRef {
68
14005997586
            symbol,
69
14005997586
            marker: PhantomData,
70
14005997586
        }
71
14005997586
    }
72
}
73

            
74
pub struct Symbol {
75
    symbol: SymbolRef<'static>,
76
}
77

            
78
impl Symbol {
79
    /// Takes ownership of the given pointer without changing the reference counter.
80
52816
    pub(crate) fn take(symbol: *const ffi::_function_symbol) -> Symbol {
81
52816
        Symbol {
82
52816
            symbol: SymbolRef::new(symbol),
83
52816
        }
84
52816
    }
85

            
86
    /// Protects the given pointer.
87
668556
    pub(crate) fn new(symbol: *const ffi::_function_symbol) -> Symbol {
88
668556
        unsafe { ffi::protect_function_symbol(symbol) };
89
668556
        Symbol {
90
668556
            symbol: SymbolRef::new(symbol),
91
668556
        }
92
668556
    }
93
}
94

            
95
impl Drop for Symbol {
96
721372
    fn drop(&mut self) {
97
721372
        unsafe { ffi::drop_function_symbol(self.symbol.symbol) };
98
721372
    }
99
}
100

            
101
impl Symbol {
102
685791712
    pub fn copy(&self) -> SymbolRef<'_> {
103
685791712
        self.symbol.copy()
104
685791712
    }
105
}
106

            
107
impl From<&SymbolRef<'_>> for Symbol {
108
    fn from(value: &SymbolRef) -> Self {
109
        value.protect()
110
    }
111
}
112

            
113
impl Clone for Symbol {
114
    fn clone(&self) -> Self {
115
        self.copy().protect()
116
    }
117
}
118

            
119
impl Deref for Symbol {
120
    type Target = SymbolRef<'static>;
121

            
122
74089360
    fn deref(&self) -> &Self::Target {
123
74089360
        &self.symbol
124
74089360
    }
125
}
126

            
127
impl fmt::Display for Symbol {
128
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129
        write!(f, "{}", self.name())
130
    }
131
}
132

            
133
impl fmt::Debug for Symbol {
134
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135
        write!(f, "{}", self.name())
136
    }
137
}
138

            
139
impl Hash for Symbol {
140
    fn hash<H: Hasher>(&self, state: &mut H) {
141
        self.copy().hash(state)
142
    }
143
}
144

            
145
impl PartialEq for Symbol {
146
12
    fn eq(&self, other: &Self) -> bool {
147
12
        self.copy().eq(&other.copy())
148
12
    }
149
}
150

            
151
impl PartialOrd for Symbol {
152
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
153
        Some(self.copy().cmp(&other.copy()))
154
    }
155
}
156

            
157
impl Ord for Symbol {
158
    fn cmp(&self, other: &Self) -> Ordering {
159
        self.copy().cmp(&other.copy())
160
    }
161
}
162

            
163
impl Borrow<SymbolRef<'static>> for Symbol {
164
24349260
    fn borrow(&self) -> &SymbolRef<'static> {
165
24349260
        &self.symbol
166
24349260
    }
167
}
168

            
169
impl Eq for Symbol {}