Skip to main content

lunar_lib/
vec_ext.rs

1use std::collections::HashSet;
2
3pub trait VecExtensions<T> {
4    fn push_unique(&mut self, item: T)
5    where
6        T: PartialEq;
7
8    fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
9    where
10        T: PartialEq;
11
12    fn deduplicate(&mut self)
13    where
14        T: std::hash::Hash + Eq + Copy;
15}
16
17impl<T> VecExtensions<T> for Vec<T> {
18    fn push_unique(&mut self, item: T)
19    where
20        T: PartialEq,
21    {
22        if !self.contains(&item) {
23            self.push(item);
24        }
25    }
26
27    fn extend_unique(&mut self, iter: impl IntoIterator<Item = T>)
28    where
29        T: PartialEq,
30    {
31        iter.into_iter().for_each(|i| {
32            self.push_unique(i);
33        });
34    }
35
36    fn deduplicate(&mut self)
37    where
38        T: std::hash::Hash + Eq + Copy,
39    {
40        let mut seen = HashSet::new();
41        self.retain(|t| seen.insert(*t));
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use crate::vec_ext::VecExtensions;
48
49    #[test]
50    fn deduplicate() {
51        let mut vec = vec![0, 1, 2, 2, 1, 0];
52        vec.deduplicate();
53    }
54
55    #[test]
56    fn push_unique() {
57        let mut vec = vec![0, 1, 2];
58        vec.push_unique(2);
59        assert_eq!(vec, vec![0, 1, 2])
60    }
61
62    #[test]
63    fn extend_unique() {
64        let mut vec = vec![0, 1, 2];
65        vec.extend_unique([1, 2, 3]);
66        assert_eq!(vec, vec![0, 1, 2, 3])
67    }
68}