1use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5
6pub type StringId = u32;
8
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
11pub struct SymbolTable {
12 symbols: Vec<String>,
13 index: BTreeMap<String, StringId>,
14}
15
16impl SymbolTable {
17 #[must_use]
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 pub fn intern(&mut self, value: &str) -> StringId {
29 if let Some(id) = self.index.get(value) {
30 return *id;
31 }
32 let id = u32::try_from(self.symbols.len()).expect("symbol table overflow");
33 let owned = value.to_string();
34 self.symbols.push(owned.clone());
35 self.index.insert(owned, id);
36 id
37 }
38
39 #[must_use]
41 #[allow(clippy::as_conversions)]
42 pub fn resolve(&self, id: StringId) -> Option<&str> {
43 self.symbols.get(id as usize).map(String::as_str)
45 }
46
47 #[must_use]
49 pub fn len(&self) -> usize {
50 self.symbols.len()
51 }
52
53 #[must_use]
55 pub fn is_empty(&self) -> bool {
56 self.symbols.is_empty()
57 }
58}