use std::collections::BTreeSet; use std::convert::AsRef; use elsa::FrozenIndexSet; struct StringInterner { set: FrozenIndexSet, } impl StringInterner { fn new() -> Self { StringInterner { set: FrozenIndexSet::new(), } } fn get_or_intern(&self, value: T) -> usize where T: AsRef, { // TODO use Entry in case the standard Entry API gets improved // (here to avoid premature allocation or double lookup) self.set.insert_full(value.as_ref().to_string()).0 } fn get(&self, value: T) -> Option where T: AsRef, { self.set.get_full(value.as_ref()).map(|(i, _r)| i) } fn resolve(&self, index: usize) -> Option<&str> { self.set.get_index(index) } } fn main() { let interner = StringInterner::new(); let lonely = interner.get_or_intern("lonely"); let best_friend = interner.get_or_intern("best friend"); let threes_a_crowd = interner.get_or_intern("threes a crowd"); let rando = interner.get_or_intern("rando"); let _facebook = interner.get_or_intern("facebook"); let best_friend_2 = interner.get_or_intern("best friend"); let best_friend_3 = interner.get("best friend").unwrap(); let best_friend_ref = interner.resolve(best_friend).unwrap(); let mut set = BTreeSet::new(); set.insert(lonely); set.insert(best_friend); set.insert(threes_a_crowd); set.insert(rando); set.insert(best_friend_2); assert_eq!(set.len(), 4); assert_eq!(best_friend, best_friend_2); assert_eq!(best_friend_2, best_friend_3); assert_eq!(best_friend_ref, "best friend"); }