lunar-lib 0.10.0

Common utilities for lunar applications
Documentation
use std::collections::HashSet;

pub trait VecExtensions<T> {
    fn push_unique(&mut self, item: T)
    where
        T: PartialEq;

    fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
    where
        T: PartialEq;

    fn deduplicate(&mut self)
    where
        T: std::hash::Hash + Eq + Copy;
}

impl<T> VecExtensions<T> for Vec<T> {
    fn push_unique(&mut self, item: T)
    where
        T: PartialEq,
    {
        if !self.contains(&item) {
            self.push(item);
        }
    }

    fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
    where
        T: PartialEq,
    {
        iter.into_iter().for_each(|i| {
            self.push_unique(i);
        });
    }

    fn deduplicate(&mut self)
    where
        T: std::hash::Hash + Eq + Copy,
    {
        let mut seen = HashSet::new();
        self.retain(|t| seen.insert(*t));
    }
}

#[cfg(test)]
mod test {
    use crate::vec_ext::VecExtensions;

    #[test]
    fn deduplicate() {
        let mut vec = vec![0, 1, 2, 2, 1, 0];
        vec.deduplicate();
    }

    #[test]
    fn push_unique() {
        let mut vec = vec![0, 1, 2];
        vec.push_unique(2);
        assert_eq!(vec, vec![0, 1, 2])
    }

    #[test]
    fn extend_unique() {
        let mut vec = vec![0, 1, 2];
        vec.extend_unique([1, 2, 3]);
        assert_eq!(vec, vec![0, 1, 2, 3])
    }
}