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 {
25 if let Some(id) = self.index.get(value) {
26 return *id;
27 }
28 let id = match u32::try_from(self.symbols.len()) {
29 Ok(id) => id,
30 Err(_) => return u32::MAX,
31 };
32 let owned = value.to_string();
33 self.symbols.push(owned.clone());
34 self.index.insert(owned, id);
35 id
36 }
37
38 #[must_use]
40 #[allow(clippy::as_conversions)]
41 pub fn resolve(&self, id: StringId) -> Option<&str> {
42 self.symbols.get(id as usize).map(String::as_str)
44 }
45
46 #[must_use]
48 pub fn len(&self) -> usize {
49 self.symbols.len()
50 }
51
52 #[must_use]
54 pub fn is_empty(&self) -> bool {
55 self.symbols.is_empty()
56 }
57}