1use std::collections::HashMap;
2use std::fmt;
3
4#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
5pub struct Symbol(u32);
6
7impl fmt::Debug for Symbol {
8 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9 write!(f, "Symbol({})", self.0)
10 }
11}
12
13#[derive(Clone)]
14pub struct StringInterner {
15 map: HashMap<String, Symbol>,
16 strings: Vec<String>,
17}
18
19impl Default for StringInterner {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl StringInterner {
26 pub fn new() -> Self {
27 Self {
28 map: HashMap::new(),
29 strings: Vec::new(),
30 }
31 }
32
33 pub fn intern(&mut self, s: &str) -> Symbol {
34 if let Some(&sym) = self.map.get(s) {
35 return sym;
36 }
37 let sym = Symbol(self.strings.len() as u32);
38 self.strings.push(s.to_string());
39 self.map.insert(s.to_string(), sym);
40 sym
41 }
42
43 pub fn resolve(&self, sym: Symbol) -> &str {
44 &self.strings[sym.0 as usize]
45 }
46}