use std::collections::HashMap;
use std::fmt;
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Symbol(u32);
impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Symbol({})", self.0)
}
}
#[derive(Clone)]
pub struct StringInterner {
map: HashMap<String, Symbol>,
strings: Vec<String>,
}
impl Default for StringInterner {
fn default() -> Self {
Self::new()
}
}
impl StringInterner {
pub fn new() -> Self {
Self {
map: HashMap::new(),
strings: Vec::new(),
}
}
pub fn intern(&mut self, s: &str) -> Symbol {
if let Some(&sym) = self.map.get(s) {
return sym;
}
let sym = Symbol(self.strings.len() as u32);
self.strings.push(s.to_string());
self.map.insert(s.to_string(), sym);
sym
}
pub fn resolve(&self, sym: Symbol) -> &str {
&self.strings[sym.0 as usize]
}
}