libpitust 0.1.2

libpitust implements random utility functions I tend to use a lot
Documentation
use std::{collections::BTreeMap, fmt::Debug, marker::PhantomData};

#[derive(Clone)]
pub struct DirtySparseMap<Key: Debug + Copy + Ord, Value> {
    inner: Vec<(Key, Value)>,
    whiteout: Vec<Key>,
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SparseMap<Key: Debug + Copy + Ord, Value> {
    inner: Vec<(Key, Value)>,
    _marker: PhantomData<Key>,
}

impl<Key: Debug + Copy + Ord, Value> DirtySparseMap<Key, Value> {
    pub fn new() -> DirtySparseMap<Key, Value> {
        DirtySparseMap {
            inner: vec![],
            whiteout: vec![],
        }
    }
    pub fn clean(&mut self) {
        self.inner.reverse();
        self.whiteout.sort_unstable();
        // FIXME: this can be done much more efficiently without binsearching
        self.inner
            .retain(|k| self.whiteout.binary_search(&k.0).is_err());
        self.inner.sort_by_key(|k| k.0);
        self.inner.dedup_by_key(|k| k.0);
        self.whiteout.clear();
    }
    pub fn to_clean(mut self) -> SparseMap<Key, Value> {
        self.clean();
        SparseMap {
            inner: self.inner,
            _marker: PhantomData,
        }
    }
    pub fn put(&mut self, key: Key, value: Value) {
        self.inner.push((key, value));
    }
    pub fn del(&mut self, key: Key) {
        self.whiteout.push(key);
    }
    pub fn with_clean<R>(&mut self, f: impl FnOnce(&mut SparseMap<Key, Value>) -> R) -> R {
        self.clean();
        let mut m = SparseMap {
            inner: core::mem::take(&mut self.inner),
            _marker: PhantomData,
        };
        let res = f(&mut m);
        self.inner = m.inner;
        res
    }
}
impl<Key: Debug + Copy + Ord, Value> SparseMap<Key, Value> {
    pub fn new() -> SparseMap<Key, Value> {
        SparseMap {
            inner: vec![],
            _marker: PhantomData,
        }
    }
    pub fn to_dirty(self) -> DirtySparseMap<Key, Value> {
        DirtySparseMap {
            inner: self.inner,
            whiteout: vec![],
        }
    }
    pub fn with_dirty<R>(&mut self, f: impl FnOnce(&mut DirtySparseMap<Key, Value>) -> R) -> R {
        let mut p = DirtySparseMap {
            inner: core::mem::take(&mut self.inner),
            whiteout: vec![],
        };
        let r = f(&mut p);
        self.inner = p.to_clean().inner;
        r
    }
    pub fn from_btree(tree: BTreeMap<Key, Value>) -> SparseMap<Key, Value> {
        SparseMap {
            inner: tree.into_iter().collect(),
            _marker: PhantomData,
        }
    }
    pub fn get(&self, key: Key) -> Option<&Value> {
        let idx = self.inner.binary_search_by_key(&key, |k| k.0).ok()?;
        Some(&self.inner[idx].1)
    }
    pub fn get_mut(&mut self, key: Key) -> Option<&mut Value> {
        let idx = self.inner.binary_search_by_key(&key, |k| k.0).ok()?;
        Some(&mut self.inner[idx].1)
    }
    /// Put an element into the map. **Note that this operation takes a linear amount of time to complete, if the element does not exist in the map**.
    pub fn put(&mut self, key: Key, value: Value) {
        match self.inner.binary_search_by_key(&key, |k| k.0) {
            Ok(idx) => self.inner[idx].1 = value,
            Err(idx) => self.inner.insert(idx, (key, value)),
        }
    }
    /// Put an element into the map. **Note that this operation takes a linear amount of time to complete, if the element exists in the map**.
    pub fn del(&mut self, key: Key) {
        if let Ok(idx) = self.inner.binary_search_by_key(&key, |k| k.0) {
            self.inner.remove(idx);
        }
    }
    /// Copy all elements from the other map into this one, replacing all that do not currently exist. This operation is O(n) where N is the number of elements in both maps.
    pub fn merge(&mut self, other: SparseMap<Key, Value>) {
        let mut new = vec![];
        let mut this = core::mem::take(&mut self.inner).into_iter().peekable();
        let mut other = other.inner.into_iter().peekable();
        while let (Some(a), Some(b)) = (this.peek(), other.peek()) {
            if a.0 == b.0 {
                this.next();
            } else if a.0 < b.0 {
                new.push(this.next().unwrap());
            } else {
                new.push(other.next().unwrap());
            }
        }
        while let Some(el) = this.next() {
            new.push(el);
        }
        while let Some(el) = other.next() {
            new.push(el);
        }
        self.inner = new;
    }
    pub fn len(&self) -> usize {
        self.inner.len()
    }
    pub fn iter(&self) -> impl Iterator<Item = (Key, &Value)> {
        self.inner.iter().map(|(k, v)| (*k, v))
    }
    pub fn iter_mut(&mut self) -> impl Iterator<Item = (Key, &mut Value)> {
        self.inner.iter_mut().map(|(k, v)| (*k, v))
    }
}

impl<Key: Debug + Copy + Ord, Value: Debug> Debug for SparseMap<Key, Value> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_map().entries(self.iter()).finish()
    }
}