use rustc_hash::FxHashMap;
use super::types::StringId;
#[derive(Debug, Default)]
pub struct StringTable {
string_to_id: FxHashMap<String, StringId>,
id_to_string: Vec<String>,
}
impl StringTable {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn intern(&mut self, s: &str) -> StringId {
if let Some(&id) = self.string_to_id.get(s) {
return id;
}
let len = self.id_to_string.len();
debug_assert!(
len < u32::MAX as usize,
"StringTable overflow: cannot intern more than {} strings",
u32::MAX
);
#[allow(clippy::cast_possible_truncation)] let id = StringId(len as u32);
self.id_to_string.push(s.to_string());
self.string_to_id.insert(s.to_string(), id);
id
}
#[must_use]
pub fn get(&self, id: StringId) -> Option<&str> {
self.id_to_string.get(id.0 as usize).map(String::as_str)
}
#[must_use]
pub fn get_id(&self, s: &str) -> Option<StringId> {
self.string_to_id.get(s).copied()
}
#[must_use]
pub fn len(&self) -> usize {
self.id_to_string.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.id_to_string.is_empty()
}
}