catallaxy_runtime/
symbol.rs1use std::sync::LazyLock;
4
5use parking_lot::RwLock;
6use rustc_hash::FxHashMap;
7
8#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
9pub struct Sym(pub u32);
10
11struct Interner {
12 map: FxHashMap<&'static str, Sym>,
13 names: Vec<&'static str>,
14}
15
16static INTERNER: LazyLock<RwLock<Interner>> =
17 LazyLock::new(|| RwLock::new(Interner { map: FxHashMap::default(), names: Vec::new() }));
18
19pub fn intern(s: &str) -> Sym {
20 if let Some(&sym) = INTERNER.read().map.get(s) {
21 return sym;
22 }
23 let mut w = INTERNER.write();
24 if let Some(&sym) = w.map.get(s) {
25 return sym;
26 }
27 let leaked: &'static str = Box::leak(s.to_string().into_boxed_str());
28 let sym = Sym(w.names.len() as u32);
29 w.names.push(leaked);
30 w.map.insert(leaked, sym);
31 sym
32}
33
34pub fn name(sym: Sym) -> &'static str {
35 INTERNER.read().names[sym.0 as usize]
36}
37
38impl std::fmt::Display for Sym {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.write_str(name(*self))
41 }
42}