use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Symbol(u32);
pub(crate) const LIST_LABEL: &str = "<>";
pub(crate) const LIST: Symbol = Symbol(0);
#[derive(Debug, Clone)]
pub struct Symbols {
names: Vec<String>,
index: HashMap<String, Symbol>,
}
impl Default for Symbols {
fn default() -> Self {
let mut s = Symbols {
names: Vec::new(),
index: HashMap::new(),
};
let list = s.intern(LIST_LABEL);
debug_assert_eq!(list, LIST);
s
}
}
impl Symbols {
pub fn intern(&mut self, name: &str) -> Symbol {
if let Some(&s) = self.index.get(name) {
return s;
}
let s = Symbol(self.names.len() as u32);
self.names.push(name.to_string());
self.index.insert(name.to_string(), s);
s
}
pub fn name(&self, s: Symbol) -> &str {
&self.names[s.0 as usize]
}
}