libpitust 0.1.2

libpitust implements random utility functions I tend to use a lot
Documentation
use std::fmt::Debug;

#[derive(Clone)]
pub struct DirtySparseSet<Key: Debug + Copy + Ord> {
    set: Vec<Key>,
}

#[derive(Clone)]
pub struct SparseSet<Key: Debug + Copy + Ord> {
    set: Vec<Key>,
}

impl<Key: Debug + Copy + Ord> DirtySparseSet<Key> {
    pub fn new() -> DirtySparseSet<Key> {
        DirtySparseSet { set: vec![] }
    }
    pub fn clean(&mut self) {
        self.set.sort_unstable();
        self.set.dedup();
    }
    pub fn to_clean(mut self) -> SparseSet<Key> {
        self.clean();
        SparseSet { set: self.set }
    }
    pub fn add(&mut self, key: Key) {
        self.set.push(key);
    }
    pub fn with_clean<R>(&mut self, f: impl FnOnce(&mut SparseSet<Key>) -> R) -> R {
        self.clean();
        let mut m = SparseSet {
            set: core::mem::take(&mut self.set),
        };
        let res = f(&mut m);
        self.set = m.set;
        res
    }
}
impl<Key: Debug + Copy + Ord> SparseSet<Key> {
    pub fn new() -> SparseSet<Key> {
        SparseSet { set: vec![] }
    }
    pub fn to_dirty(self) -> DirtySparseSet<Key> {
        DirtySparseSet { set: self.set }
    }
    pub fn to_vec(self) -> Vec<Key> {
        self.set
    }
    pub fn pick_subset(&self, mut f: impl FnMut(Key) -> bool) -> SparseSet<Key> {
        let mut new_set = vec![];
        for &elem in &self.set {
            if f(elem) {
                new_set.push(elem);
            }
        }
        SparseSet { set: new_set }
    }
    pub fn with_dirty<R>(&mut self, f: impl FnOnce(&mut DirtySparseSet<Key>) -> R) -> R {
        let mut p = DirtySparseSet {
            set: core::mem::take(&mut self.set),
        };
        let r = f(&mut p);
        self.set = p.to_clean().set;
        r
    }
    pub fn has(&self, key: Key) -> bool {
        self.set.binary_search_by_key(&key, |&k| k).is_ok()
    }
    pub fn del(&mut self, key: Key) {
        if let Ok(idx) = self.set.binary_search_by_key(&key, |&k| k) {
            self.set.remove(idx);
        }
    }
    /// Union the two sets. This operation is O(n) where N is the number of elements in both maps.
    pub fn union(&mut self, other: SparseSet<Key>) {
        let mut new = vec![];
        let mut this = core::mem::take(&mut self.set).into_iter().peekable();
        let mut other = other.set.into_iter().peekable();
        while let (Some(a), Some(b)) = (this.peek(), other.peek()) {
            if a == b {
                this.next();
            } else if a < b {
                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.set = new;
    }
    pub fn len(&self) -> usize {
        self.set.len()
    }
    pub fn iter(&self) -> impl Iterator<Item = Key> {
        self.set.iter().copied()
    }
}

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