vecset.rs

 1/// A set backed by a `Vec`, preserving insertion order.
 2///
 3/// Suitable for small collections where the item count doesn't justify
 4/// the overhead of a hash set. Iterates in insertion order.
 5#[derive(Debug, Clone)]
 6pub struct VecSet<T> {
 7    items: Vec<T>,
 8}
 9
10impl<T> Default for VecSet<T> {
11    fn default() -> Self {
12        Self { items: Vec::new() }
13    }
14}
15
16impl<T: PartialEq> VecSet<T> {
17    pub fn new() -> Self {
18        Self::default()
19    }
20
21    /// Inserts a value. Returns `true` if the value was newly inserted,
22    /// `false` if it was already present.
23    pub fn insert(&mut self, value: T) -> bool {
24        if self.items.contains(&value) {
25            false
26        } else {
27            self.items.push(value);
28            true
29        }
30    }
31
32    /// Removes a value. Returns `true` if the value was present.
33    pub fn remove(&mut self, value: &T) -> bool {
34        if let Some(pos) = self.items.iter().position(|item| item == value) {
35            self.items.swap_remove(pos);
36            true
37        } else {
38            false
39        }
40    }
41
42    pub fn contains(&self, value: &T) -> bool {
43        self.items.contains(value)
44    }
45
46    pub fn len(&self) -> usize {
47        self.items.len()
48    }
49
50    pub fn is_empty(&self) -> bool {
51        self.items.is_empty()
52    }
53
54    pub fn iter(&self) -> std::slice::Iter<'_, T> {
55        self.items.iter()
56    }
57
58    pub fn retain(&mut self, f: impl FnMut(&T) -> bool) {
59        self.items.retain(f);
60    }
61}
62
63impl<T> IntoIterator for VecSet<T> {
64    type Item = T;
65    type IntoIter = std::vec::IntoIter<T>;
66
67    fn into_iter(self) -> Self::IntoIter {
68        self.items.into_iter()
69    }
70}
71
72impl<'a, T> IntoIterator for &'a VecSet<T> {
73    type Item = &'a T;
74    type IntoIter = std::slice::Iter<'a, T>;
75
76    fn into_iter(self) -> Self::IntoIter {
77        self.items.iter()
78    }
79}