Phase 2: InternedStr and Interner types (infrastructure)
This commit is contained in:
@@ -2,9 +2,78 @@ use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
|
||||
use super::style::{ComputedStyle, StyleSheet};
|
||||
use compact_str::CompactString;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct InternedStr(u32);
|
||||
|
||||
impl InternedStr {
|
||||
pub const fn from_raw(id: u32) -> Self {
|
||||
Self(id)
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl InternedStr {
|
||||
pub fn eq_str(&self, other: &str) -> bool {
|
||||
with_interner(|interner| interner.lookup(*self) == other)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Interner {
|
||||
strings: Vec<String>,
|
||||
map: HashMap<String, u32>,
|
||||
next_id: u32,
|
||||
}
|
||||
|
||||
impl Interner {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
strings: Vec::new(),
|
||||
map: HashMap::new(),
|
||||
next_id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intern(&mut self, s: &str) -> InternedStr {
|
||||
if let Some(&id) = self.map.get(s) {
|
||||
return InternedStr(id);
|
||||
}
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.strings.push(s.to_string());
|
||||
self.map.insert(s.to_string(), id);
|
||||
InternedStr(id)
|
||||
}
|
||||
|
||||
pub fn lookup(&self, id: InternedStr) -> &str {
|
||||
&self.strings[id.0 as usize]
|
||||
}
|
||||
|
||||
pub fn intern_or_none(&mut self, s: Option<&str>) -> Option<InternedStr> {
|
||||
s.map(|s| self.intern(s))
|
||||
}
|
||||
}
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
thread_local! {
|
||||
static GLOBAL_INTERNER: RefCell<Interner> = RefCell::new(Interner::new());
|
||||
}
|
||||
|
||||
pub fn with_interner<F, R>(f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Interner) -> R,
|
||||
{
|
||||
GLOBAL_INTERNER.with(|i| f(&mut *i.borrow_mut()))
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Value {
|
||||
Str(CompactString),
|
||||
@@ -128,6 +197,7 @@ pub struct Document<'a> {
|
||||
pub variables: HashMap<String, Value>,
|
||||
pub rhei_scripts: Vec<String>,
|
||||
pub stylesheet: StyleSheet,
|
||||
pub interner: Interner,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
Reference in New Issue
Block a user