use std::borrow::Borrow;
use std::hash::Hash;
use lazy_static::lazy_static;
use crate::interner::Interner;
use crate::token::Internable;
use crate::Tok;
lazy_static! {
static ref SINGLETON: Interner = Interner::new();
}
#[macro_export]
macro_rules! i {
($ty:ty : $expr:expr) => {{
thread_local! {
static VALUE: Tok<<$ty as ToOwned>::Owned> = $crate::i($expr as &$ty);
}
VALUE.with(|v| v.clone())
}};
}
#[must_use]
pub fn i<Q>(q: &Q) -> Tok<Q::Owned>
where
Q: ?Sized + Eq + Hash + ToOwned,
Q::Owned: Borrow<Q> + Internable,
{
SINGLETON.i(q)
}
#[must_use]
pub fn ev<'a, T: Internable>(s: impl IntoIterator<Item = &'a Tok<T>>) -> Vec<T> {
s.into_iter().map(|t| (**t).clone()).collect()
}
pub fn sweep_t<T: Internable>() -> usize { SINGLETON.sweep_t::<T>() }
pub fn sweep() -> usize { SINGLETON.sweep() }
pub fn iv<T: Internable>(s: impl IntoIterator<Item = T>) -> Tok<Vec<Tok<T>>> { SINGLETON.iv(s) }
pub fn ibv<'a, Q>(s: impl IntoIterator<Item = &'a Q>) -> Tok<Vec<Tok<Q::Owned>>>
where
Q: ?Sized + Eq + Hash + ToOwned + 'a,
Q::Owned: Internable,
{
SINGLETON.ibv(s)
}
#[cfg(test)]
mod test {
use std::any::{type_name, type_name_of_val};
use super::i;
use crate::Tok;
#[test]
pub fn statics() {
let a = i!(str: "foo");
let b = i!(str: "foo");
let c = i("foo");
assert_eq!(a, b);
assert_eq!(a, c);
let v = i!([Tok<String>]: &[i("foo"), i("bar"), i("baz")]);
assert_eq!(type_name_of_val(&v), type_name::<Tok<Vec<Tok<String>>>>());
}
}