1 use crate::syntax::set::UnorderedSet as Set; 2 use once_cell::sync::OnceCell; 3 use std::sync::{Mutex, PoisonError}; 4 5 #[derive(Copy, Clone, Default)] 6 pub struct InternedString(&'static str); 7 8 impl InternedString { str(self) -> &'static str9 pub fn str(self) -> &'static str { 10 self.0 11 } 12 } 13 intern(s: &str) -> InternedString14pub fn intern(s: &str) -> InternedString { 15 static INTERN: OnceCell<Mutex<Set<&'static str>>> = OnceCell::new(); 16 17 let mut set = INTERN 18 .get_or_init(|| Mutex::new(Set::new())) 19 .lock() 20 .unwrap_or_else(PoisonError::into_inner); 21 22 InternedString(match set.get(s) { 23 Some(interned) => *interned, 24 None => { 25 let interned = Box::leak(Box::from(s)); 26 set.insert(interned); 27 interned 28 } 29 }) 30 } 31