libpitust 0.1.2

libpitust implements random utility functions I tend to use a lot
Documentation
use std::{borrow::Borrow, collections::HashMap, fmt::Debug, hash::Hash, ops::Index};

use crate::index::{Idx, vec::IndexVec};

pub struct InternMap<Key: Idx, Value: Eq + Hash + Clone> {
    // TODO: we don't need to store values twice if we are more clever about storage here
    idx_map: IndexVec<Key, Value>,
    lut_map: HashMap<Value, Key>,
}
impl<Key: Idx, Value: Eq + Hash + Clone> InternMap<Key, Value> {
    pub fn new() -> InternMap<Key, Value> {
        InternMap {
            idx_map: IndexVec::new(),
            lut_map: HashMap::new(),
        }
    }
    pub fn push_unindexed(&mut self, val: Value) -> Key {
        self.idx_map.push(val)
    }
    pub fn push<'a, V: ?Sized>(&mut self, val: &'a V) -> Key
    where
        V: Eq + Hash + ToOwned<Owned = Value>,
        Value: Borrow<V>,
    {
        if let Some(k) = self.lut_map.get(&val).copied() {
            k
        } else {
            let k = self.idx_map.push(val.to_owned());
            self.lut_map.insert(val.to_owned(), k);
            k
        }
    }
    pub fn try_push<'a, V: ?Sized>(&self, val: &'a V) -> Option<Key>
    where
        V: Eq + Hash,
        Value: Borrow<V>,
    {
        if let Some(k) = self.lut_map.get(&val).copied() {
            Some(k)
        } else {
            None
        }
    }
    pub fn watermark(&self) -> usize {
        self.idx_map.len()
    }
}
impl<Key: Idx, Value: Eq + Hash + Clone> Index<Key> for InternMap<Key, Value> {
    type Output = Value;

    fn index(&self, index: Key) -> &Value {
        &self.idx_map[index]
    }
}
impl<Key: Idx, Value: Eq + Hash + Clone> Default for InternMap<Key, Value> {
    fn default() -> Self {
        InternMap::new()
    }
}

impl<Key: Idx, Value: Eq + Hash + Clone + Debug> Debug for InternMap<Key, Value> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_map().entries(self.idx_map.iter()).finish()
    }
}