1use std::collections::HashMap;
4
5pub const KEY_NONE: u32 = u32::MAX;
7
8#[derive(Default, Debug)]
14pub struct NameTable {
15 name_to_key: HashMap<String, u32>,
17 names: Vec<String>,
19 node_key: Vec<u32>,
22}
23
24impl NameTable {
25 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn intern(&mut self, name: &str) -> u32 {
31 if let Some(&k) = self.name_to_key.get(name) {
32 return k;
33 }
34 let k = self.names.len() as u32;
35 self.name_to_key.insert(name.to_string(), k);
36 self.names.push(name.to_string());
37 k
38 }
39
40 pub fn name(&self, key: u32) -> &str {
42 self.names.get(key as usize).map(|s| s.as_str()).unwrap_or("")
43 }
44
45 pub fn var_key(&self, idx: usize) -> Option<u32> {
47 match self.node_key.get(idx) {
48 Some(&k) if k != KEY_NONE => Some(k),
49 _ => None,
50 }
51 }
52
53 pub fn raw_key(&self, idx: usize) -> u32 {
55 self.node_key.get(idx).copied().unwrap_or(KEY_NONE)
56 }
57
58 pub fn key_slots(&self) -> usize {
60 self.node_key.len()
61 }
62
63 pub fn extend_owned(&mut self, base: usize, names: &[Option<String>]) {
67 if self.node_key.len() < base + names.len() {
68 self.node_key.resize(base + names.len(), KEY_NONE);
69 }
70 for (i, name) in names.iter().enumerate() {
71 if let Some(n) = name {
72 self.node_key[base + i] = self.intern(n);
73 }
74 }
75 }
76}