1use std::borrow::Borrow;
2use std::hash::Hash;
3
4use lazy_static::lazy_static;
5
6use crate::interner::Interner;
7use crate::token::Internable;
8use crate::Tok;
9
10lazy_static! {
11 static ref SINGLETON: Interner = Interner::new();
12}
13
14#[macro_export]
19macro_rules! i {
20 ($ty:ty : $expr:expr) => {{
21 thread_local! {
22 static VALUE: $crate::Tok<<$ty as ToOwned>::Owned> = $crate::i($expr as &$ty);
23 }
24 VALUE.with(|v| v.clone())
25 }};
26}
27
28#[must_use]
31pub fn i<Q>(q: &Q) -> Tok<Q::Owned>
32where
33 Q: ?Sized + Eq + Hash + ToOwned,
34 Q::Owned: Borrow<Q> + Internable,
35{
36 SINGLETON.i(q)
37}
38
39#[must_use]
42pub fn ev<'a, T: Internable>(s: impl IntoIterator<Item = &'a Tok<T>>) -> Vec<T> {
43 s.into_iter().map(|t| (**t).clone()).collect()
44}
45
46pub fn sweep_t<T: Internable>() -> usize { SINGLETON.sweep_t::<T>() }
50
51pub fn sweep() -> usize { SINGLETON.sweep() }
54
55pub fn iv<T: Internable>(s: impl IntoIterator<Item = T>) -> Tok<Vec<Tok<T>>> { SINGLETON.iv(s) }
57
58pub fn ibv<'a, Q>(s: impl IntoIterator<Item = &'a Q>) -> Tok<Vec<Tok<Q::Owned>>>
60where
61 Q: ?Sized + Eq + Hash + ToOwned + 'a,
62 Q::Owned: Internable,
63{
64 SINGLETON.ibv(s)
65}
66
67#[cfg(test)]
68mod test {
69 use std::any::{type_name, type_name_of_val};
70
71 use super::i;
72 use crate::Tok;
73
74 #[test]
75 pub fn statics() {
76 let a = i!(str: "foo");
77 let b = i!(str: "foo");
78 let c = i("foo");
79 assert_eq!(a, b);
80 assert_eq!(a, c);
81 let v = i!([Tok<String>]: &[i("foo"), i("bar"), i("baz")]);
82 assert_eq!(type_name_of_val(&v), type_name::<Tok<Vec<Tok<String>>>>());
83 }
84}