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}