use std::{ borrow::{Borrow, ToOwned}, collections::HashMap, hash::Hash, }; use crate::Index; /// Maps user keys to internal `Index` handles. /// /// Renamed from the former `IndexMap` to avoid colliding with the `indexmap` /// crate. Power users can promote `&K` to `Index` via `get_or_create` and /// skip the lookup on subsequent hot-path calls. #[derive(Debug)] pub struct KeyTable(HashMap); impl KeyTable where K: Eq + Hash, { pub fn new() -> Self { Self(HashMap::new()) } pub fn get>(&self, k: &Q) -> Option where K: Borrow, { self.0.get(k).cloned() } pub fn get_or_create>(&mut self, k: &Q) -> Index where K: Borrow, { if let Some(idx) = self.0.get(k) { *idx } else { let idx = Index::from(self.0.len()); self.0.insert(k.to_owned(), idx); idx } } pub fn key(&self, idx: Index) -> Option<&K> { self.0 .iter() .find(|&(_, value)| *value == idx) .map(|(key, _)| key) } pub fn keys(&self) -> impl Iterator { self.0.keys() } pub fn len(&self) -> usize { self.0.len() } pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Default for KeyTable where K: Eq + Hash, { fn default() -> Self { KeyTable::new() } }