blob: 4f01b0d274945a197232e08e26e1181a3aa9a527 [file] [log] [blame]
Joel Galenson2370d122020-10-12 16:02:26 -07001extern crate weak_table;
2
3use weak_table::WeakHashSet;
4use std::ops::Deref;
5use std::rc::{Rc, Weak};
6
7#[derive(Clone, Debug)]
8pub struct Symbol(Rc<str>);
9
10impl PartialEq for Symbol {
11 fn eq(&self, other: &Symbol) -> bool {
12 Rc::ptr_eq(&self.0, &other.0)
13 }
14}
15
16impl Eq for Symbol {}
17
18impl Deref for Symbol {
19 type Target = str;
20 fn deref(&self) -> &str {
21 &self.0
22 }
23}
24
25#[derive(Debug, Default)]
26pub struct SymbolTable(WeakHashSet<Weak<str>>);
27
28impl SymbolTable {
29 pub fn new() -> Self {
30 Self::default()
31 }
32
33 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]
45fn 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}