use typetoken::{token, Token};
use std::marker::PhantomData;
struct Interner<T: Token> {
v: Vec<String>,
_token: PhantomData<T>,
}
struct InternedString<T: Token> {
index: usize,
_token: PhantomData<T>,
}
impl<T: Token> Interner<T> {
fn new(_token: T) -> Self {
Self{ v: vec![], _token: PhantomData::default() }
}
fn intern(&mut self, s: &str) -> InternedString<T> {
let index;
if let Some(idx) = self.v.iter().position(|x| x == s) {
index = idx;
} else {
index = self.v.len();
self.v.push(s.to_string());
}
InternedString{
index,
_token: PhantomData::default(),
}
}
fn resolve(&self, s: InternedString<T>) -> &str {
&self.v[s.index]
}
}
fn main() {
token!(token1);
let mut pool1 = Interner::new(token1);
token!(token2);
let mut pool2 = Interner::new(token2);
let str1 = pool1.intern("abcd");
let str2 = pool2.intern("1234");
println!("{}", pool1.resolve(str1));
println!("{}", pool2.resolve(str2));
}