map_trait/
set.rs

1use std::borrow::Borrow;
2use std::hash::Hash;
3
4/// A generic Set trait
5///
6/// # Examples
7///
8/// This is a toy example of a set which reexposes an inner set and stores the
9/// most recent value to be inserted. Because the LastInsertSet implements
10/// Set, it can be seamlessly used as a replacement for other sets.
11/// ```
12/// use std::borrow::Borrow;
13/// use std::hash::Hash;
14/// use std::collections::HashSet;
15///
16/// use map_trait::set::Set;
17/// struct LastInsertSet<T, S> {
18///     inner_set: S,
19///     last_value: T,
20/// }
21///
22/// impl<T, S> LastInsertSet<T, S>
23/// where
24///     T: Copy,
25///     S: Set<T>
26/// {
27///     fn new(mut set: S, value: T) -> Self {
28///         set.insert(value);
29///         LastInsertSet {
30///             inner_set: set,
31///             last_value: value,
32///         }
33///     }
34///
35///     fn get_last_insert(&self) -> &T {
36///         &self.last_value
37///     }
38/// }
39///
40/// impl<T, S> Set<T> for LastInsertSet<T, S>
41/// where
42///     T: Copy,
43///     S: Set<T>
44/// {
45///
46///     #[inline]
47///     fn contains<Q: ?Sized>(&self, value: &Q) -> bool
48///     where
49///         T: Borrow<Q>,
50///         Q: Hash + Eq + Ord
51///     {
52///         self.inner_set.contains(value)
53///     }
54///
55///     fn insert(&mut self, value: T) -> bool
56///     {
57///         self.last_value = value;
58///         self.inner_set.insert(value)
59///     }
60///
61/// }
62///
63/// # fn main() {
64///     let mut set = LastInsertSet::new(HashSet::new(), 0);
65///     assert_eq!(set.get_last_insert(), &0);
66///     assert!(set.contains(&0));
67///     assert!(set.insert(1));
68///     assert!(set.contains(&1));
69///     assert_eq!(set.get_last_insert(), &1);
70/// # }
71/// ```
72
73pub trait Set<T> {
74    fn contains<Q: ?Sized>(&self, value: &Q) -> bool
75    where
76        T: Borrow<Q>,
77        Q: Hash + Eq + Ord;
78
79    fn insert(&mut self, value: T) -> bool;
80}
81
82impl<T, S> Set<T> for std::collections::HashSet<T, S>
83where
84    T: Hash + Eq,
85    S: std::hash::BuildHasher,
86{
87    #[inline]
88    fn contains<Q: ?Sized>(&self, value: &Q) -> bool
89    where
90        T: Borrow<Q>,
91        Q: Hash + Eq + Ord,
92    {
93        std::collections::HashSet::contains(self, value)
94    }
95
96    #[inline]
97    fn insert(&mut self, value: T) -> bool {
98        std::collections::HashSet::insert(self, value)
99    }
100}
101
102impl<T> Set<T> for std::collections::BTreeSet<T>
103where
104    T: Ord,
105{
106    #[inline]
107    fn contains<Q: ?Sized>(&self, value: &Q) -> bool
108    where
109        T: Borrow<Q>,
110        Q: Hash + Eq + Ord,
111    {
112        std::collections::BTreeSet::contains(self, value)
113    }
114
115    #[inline]
116    fn insert(&mut self, value: T) -> bool {
117        std::collections::BTreeSet::insert(self, value)
118    }
119}
120
121#[cfg(test)]
122mod tests {
123    use super::*;
124
125    fn assert_set_contains<T>(set: &impl Set<T>, value: T)
126    where
127        T: Hash + Eq + Ord,
128    {
129        assert!(set.contains(&value));
130    }
131
132    fn assert_set_insert<T>(set: &mut impl Set<T>, value: T)
133    where
134        T: Hash + Eq + Ord,
135    {
136        assert!(set.insert(value));
137    }
138
139    #[test]
140    fn test_hash_set() {
141        let mut set = std::collections::HashSet::new();
142
143        assert_set_insert(&mut set, 1);
144        assert_set_contains(&set, 1);
145    }
146
147    #[test]
148    fn test_btree_set() {
149        let mut set = std::collections::BTreeSet::new();
150
151        assert_set_insert(&mut set, 1);
152        assert_set_contains(&set, 1);
153    }
154}