1 extern crate weak_table;
2
3 use weak_table::WeakHashSet;
4 use std::ops::Deref;
5 use std::rc::{Rc, Weak};
6
7 #[derive(Clone, Debug)]
8 pub struct Symbol(Rc<str>);
9
10 impl PartialEq for Symbol {
eq(&self, other: &Symbol) -> bool11 fn eq(&self, other: &Symbol) -> bool {
12 Rc::ptr_eq(&self.0, &other.0)
13 }
14 }
15
16 impl Eq for Symbol {}
17
18 impl Deref for Symbol {
19 type Target = str;
deref(&self) -> &str20 fn deref(&self) -> &str {
21 &self.0
22 }
23 }
24
25 #[derive(Debug, Default)]
26 pub struct SymbolTable(WeakHashSet<Weak<str>>);
27
28 impl SymbolTable {
new() -> Self29 pub fn new() -> Self {
30 Self::default()
31 }
32
intern(&mut self, name: &str) -> Symbol33 pub fn intern(&mut self, name: &str) -> Symbol {
34 if let Some(rc) = self.0.get(name) {
35 Symbol(rc)
36 } else {
37 let rc = Rc::<str>::from(name);
38 self.0.insert(Rc::clone(&rc));
39 Symbol(rc)
40 }
41 }
42 }
43
44 #[test]
interning()45 fn interning() {
46 let mut tab = SymbolTable::new();
47
48 let a0 = tab.intern("a");
49 let a1 = tab.intern("a");
50 let b = tab.intern("b");
51
52 assert_eq!(a0, a1);
53 assert_ne!(a0, b);
54 }
55