mod fmt;
use intaglio::{Symbol as SymbolInner, bytes::SymbolTable};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Symbol(SymbolInner);
impl Default for Symbol {
fn default() -> Self {
Self(SymbolInner::new(0))
}
}
impl From<Symbol> for usize {
fn from(symbol: Symbol) -> usize {
symbol.0.id() as usize
}
}
#[derive(Debug)]
pub struct Interner(SymbolTable);
impl Interner {
pub fn new() -> Self {
let mut interner = SymbolTable::new();
interner
.intern(b"<invalid symbol>".as_ref())
.expect("failed to intern symbol");
Self(interner)
}
#[cfg(test)]
pub fn get<T>(&self, value: T) -> Option<Symbol>
where
T: AsRef<[u8]>,
{
self.0
.check_interned(value.as_ref())
.map(Symbol)
}
pub fn get_or_intern<T>(&mut self, value: T) -> Symbol
where
T: AsRef<[u8]>,
{
let value = value.as_ref().to_owned();
Symbol(
self.0
.intern(value)
.expect("failed to intern symbol")
)
}
pub fn resolve(&self, symbol: Symbol) -> Option<&[u8]> {
self.0.get(symbol.0)
}
#[cfg(test)]
pub fn len(&self) -> usize {
self.0.len() - 1
}
}