Skip to main content

lintspec_core/
interner.rs

1//! String interner used by data structures.
2use std::sync::LazyLock;
3
4/// The global string interner used by the parsers and other data structures.
5pub static INTERNER: LazyLock<Interner> = LazyLock::new(Interner::new);
6
7/// The reference to an interned string from the [`INTERNER`].
8///
9/// This type can be compared to rapidly check for string equality.
10#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub struct Symbol(inturn::Symbol);
12
13impl Symbol {
14    /// Resolve the symbol to its interned string slice.
15    pub fn resolve_with(self, interner: &'static Interner) -> &'static str {
16        interner.resolve(self)
17    }
18}
19
20/// A string interner, uses [`inturn`] under the hood.
21#[derive(Default)]
22pub struct Interner(inturn::Interner);
23
24impl Interner {
25    /// Create a new interner.
26    #[must_use]
27    pub fn new() -> Self {
28        Self(inturn::Interner::new())
29    }
30
31    /// Intern a string reference if needed, and return the corresponding [`Symbol`].
32    ///
33    /// If the argument has a `'static` lifetime, use [`get_or_intern_static`](Self::get_or_intern_static) instead.
34    pub fn get_or_intern(&self, string: impl AsRef<str>) -> Symbol {
35        Symbol(self.0.intern(string.as_ref()))
36    }
37
38    /// Intern a static string slice if needed, and return the corresponding [`Symbol`].
39    pub fn get_or_intern_static(&self, string: &'static str) -> Symbol {
40        Symbol(self.0.intern_static(string))
41    }
42
43    /// Resolve a symbol to its interned string slice.
44    pub fn resolve(&'static self, sym: Symbol) -> &'static str {
45        self.0.resolve(sym.0)
46    }
47}