hashset_ext/
lib.rs

1use std::collections::HashSet;
2use std::ops::{BitOr, BitAnd, BitXor, Sub, BitOrAssign, BitAndAssign, BitXorAssign, SubAssign};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct HashSetExt<T: Eq + std::hash::Hash>(pub HashSet<T>);
6
7impl<T: Eq + std::hash::Hash> From<Vec<T>> for HashSetExt<T> {
8    fn from(vec: Vec<T>) -> Self {
9        HashSetExt(vec.into_iter().collect())
10    }
11}
12
13impl<T: Eq + std::hash::Hash> From<HashSet<T>> for HashSetExt<T> {
14    fn from(set: HashSet<T>) -> Self {
15        HashSetExt(set)
16    }
17}
18
19// ----------------- UNION (|) -----------------
20impl<'a, 'b, T: Eq + std::hash::Hash + Clone> BitOr<&'b HashSetExt<T>> for &'a HashSetExt<T> {
21    type Output = HashSetExt<T>;
22    fn bitor(self, other: &'b HashSetExt<T>) -> Self::Output {
23        HashSetExt(self.0.union(&other.0).cloned().collect())
24    }
25}
26
27impl<'a, T: Eq + std::hash::Hash + Clone> BitOr<HashSetExt<T>> for &'a HashSetExt<T> {
28    type Output = HashSetExt<T>;
29    fn bitor(self, other: HashSetExt<T>) -> Self::Output {
30        HashSetExt(self.0.union(&other.0).cloned().collect())
31    }
32}
33
34impl<'b, T: Eq + std::hash::Hash + Clone> BitOr<&'b HashSetExt<T>> for HashSetExt<T> {
35    type Output = HashSetExt<T>;
36    fn bitor(self, other: &'b HashSetExt<T>) -> Self::Output {
37        HashSetExt(self.0.union(&other.0).cloned().collect())
38    }
39}
40
41// ----------------- INTERSECTION (&) -----------------
42impl<'a, 'b, T: Eq + std::hash::Hash + Clone> BitAnd<&'b HashSetExt<T>> for &'a HashSetExt<T> {
43    type Output = HashSetExt<T>;
44    fn bitand(self, other: &'b HashSetExt<T>) -> Self::Output {
45        HashSetExt(self.0.intersection(&other.0).cloned().collect())
46    }
47}
48
49impl<'a, T: Eq + std::hash::Hash + Clone> BitAnd<HashSetExt<T>> for &'a HashSetExt<T> {
50    type Output = HashSetExt<T>;
51    fn bitand(self, other: HashSetExt<T>) -> Self::Output {
52        HashSetExt(self.0.intersection(&other.0).cloned().collect())
53    }
54}
55
56impl<'b, T: Eq + std::hash::Hash + Clone> BitAnd<&'b HashSetExt<T>> for HashSetExt<T> {
57    type Output = HashSetExt<T>;
58    fn bitand(self, other: &'b HashSetExt<T>) -> Self::Output {
59        HashSetExt(self.0.intersection(&other.0).cloned().collect())
60    }
61}
62
63// ----------------- DIFFERENCE (-) -----------------
64impl<'a, 'b, T: Eq + std::hash::Hash + Clone> Sub<&'b HashSetExt<T>> for &'a HashSetExt<T> {
65    type Output = HashSetExt<T>;
66    fn sub(self, other: &'b HashSetExt<T>) -> Self::Output {
67        HashSetExt(self.0.difference(&other.0).cloned().collect())
68    }
69}
70
71impl<'a, T: Eq + std::hash::Hash + Clone> Sub<HashSetExt<T>> for &'a HashSetExt<T> {
72    type Output = HashSetExt<T>;
73    fn sub(self, other: HashSetExt<T>) -> Self::Output {
74        HashSetExt(self.0.difference(&other.0).cloned().collect())
75    }
76}
77
78impl<'b, T: Eq + std::hash::Hash + Clone> Sub<&'b HashSetExt<T>> for HashSetExt<T> {
79    type Output = HashSetExt<T>;
80    fn sub(self, other: &'b HashSetExt<T>) -> Self::Output {
81        HashSetExt(self.0.difference(&other.0).cloned().collect())
82    }
83}
84
85// ----------------- SYMMETRIC DIFFERENCE (^) -----------------
86impl<'a, 'b, T: Eq + std::hash::Hash + Clone> BitXor<&'b HashSetExt<T>> for &'a HashSetExt<T> {
87    type Output = HashSetExt<T>;
88    fn bitxor(self, other: &'b HashSetExt<T>) -> Self::Output {
89        HashSetExt(self.0.symmetric_difference(&other.0).cloned().collect())
90    }
91}
92
93impl<'a, T: Eq + std::hash::Hash + Clone> BitXor<HashSetExt<T>> for &'a HashSetExt<T> {
94    type Output = HashSetExt<T>;
95    fn bitxor(self, other: HashSetExt<T>) -> Self::Output {
96        HashSetExt(self.0.symmetric_difference(&other.0).cloned().collect())
97    }
98}
99
100impl<'b, T: Eq + std::hash::Hash + Clone> BitXor<&'b HashSetExt<T>> for HashSetExt<T> {
101    type Output = HashSetExt<T>;
102    fn bitxor(self, other: &'b HashSetExt<T>) -> Self::Output {
103        HashSetExt(self.0.symmetric_difference(&other.0).cloned().collect())
104    }
105}
106
107// ----------------- IN-PLACE ASSIGN -----------------
108impl<T: Eq + std::hash::Hash + Clone> BitOrAssign for HashSetExt<T> {
109    fn bitor_assign(&mut self, other: Self) {
110        self.0.extend(other.0);
111    }
112}
113
114impl<T: Eq + std::hash::Hash + Clone> BitAndAssign for HashSetExt<T> {
115    fn bitand_assign(&mut self, other: Self) {
116        self.0 = self.0.intersection(&other.0).cloned().collect();
117    }
118}
119
120impl<T: Eq + std::hash::Hash + Clone> SubAssign for HashSetExt<T> {
121    fn sub_assign(&mut self, other: Self) {
122        self.0 = self.0.difference(&other.0).cloned().collect();
123    }
124}
125
126impl<T: Eq + std::hash::Hash + Clone> BitXorAssign for HashSetExt<T> {
127    fn bitxor_assign(&mut self, other: Self) {
128        self.0 = self.0.symmetric_difference(&other.0).cloned().collect();
129    }
130}