1use alloc::collections::BTreeSet;
2
3use crate::{Crdt, DeltaCrdt};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct GSet<T: Ord + Clone> {
29 elements: BTreeSet<T>,
30}
31
32impl<T: Ord + Clone> GSet<T> {
33 #[must_use]
35 pub fn new() -> Self {
36 Self {
37 elements: BTreeSet::new(),
38 }
39 }
40
41 pub fn insert(&mut self, value: T) -> bool {
45 self.elements.insert(value)
46 }
47
48 #[must_use]
50 pub fn contains(&self, value: &T) -> bool {
51 self.elements.contains(value)
52 }
53
54 #[must_use]
56 pub fn len(&self) -> usize {
57 self.elements.len()
58 }
59
60 #[must_use]
62 pub fn is_empty(&self) -> bool {
63 self.elements.is_empty()
64 }
65
66 pub fn iter(&self) -> impl Iterator<Item = &T> {
68 self.elements.iter()
69 }
70}
71
72impl<T: Ord + Clone> Default for GSet<T> {
73 fn default() -> Self {
74 Self::new()
75 }
76}
77
78impl<T: Ord + Clone> Crdt for GSet<T> {
79 fn merge(&mut self, other: &Self) {
80 for elem in &other.elements {
81 self.elements.insert(elem.clone());
82 }
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89pub struct GSetDelta<T: Ord + Clone> {
90 pub elements: BTreeSet<T>,
92}
93
94impl<T: Ord + Clone> DeltaCrdt for GSet<T> {
95 type Delta = GSetDelta<T>;
96
97 fn delta(&self, other: &Self) -> GSetDelta<T> {
98 GSetDelta {
99 elements: self.elements.difference(&other.elements).cloned().collect(),
100 }
101 }
102
103 fn apply_delta(&mut self, delta: &GSetDelta<T>) {
104 for elem in &delta.elements {
105 self.elements.insert(elem.clone());
106 }
107 }
108}
109
110impl<T: Ord + Clone> IntoIterator for GSet<T> {
111 type Item = T;
112 type IntoIter = alloc::collections::btree_set::IntoIter<T>;
113
114 fn into_iter(self) -> Self::IntoIter {
115 self.elements.into_iter()
116 }
117}
118
119impl<T: Ord + Clone> FromIterator<T> for GSet<T> {
120 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
121 Self {
122 elements: BTreeSet::from_iter(iter),
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn new_set_is_empty() {
133 let s = GSet::<String>::new();
134 assert!(s.is_empty());
135 assert_eq!(s.len(), 0);
136 }
137
138 #[test]
139 fn insert_and_contains() {
140 let mut s = GSet::new();
141 assert!(s.insert("a"));
142 assert!(s.contains(&"a"));
143 assert!(!s.contains(&"b"));
144 }
145
146 #[test]
147 fn insert_duplicate_returns_false() {
148 let mut s = GSet::new();
149 assert!(s.insert("a"));
150 assert!(!s.insert("a"));
151 assert_eq!(s.len(), 1);
152 }
153
154 #[test]
155 fn merge_is_union() {
156 let mut s1 = GSet::new();
157 s1.insert(1);
158 s1.insert(2);
159
160 let mut s2 = GSet::new();
161 s2.insert(2);
162 s2.insert(3);
163
164 s1.merge(&s2);
165 assert_eq!(s1.len(), 3);
166 assert!(s1.contains(&1));
167 assert!(s1.contains(&2));
168 assert!(s1.contains(&3));
169 }
170
171 #[test]
172 fn merge_is_commutative() {
173 let mut s1 = GSet::new();
174 s1.insert("a");
175
176 let mut s2 = GSet::new();
177 s2.insert("b");
178
179 let mut left = s1.clone();
180 left.merge(&s2);
181
182 let mut right = s2.clone();
183 right.merge(&s1);
184
185 assert_eq!(left, right);
186 }
187
188 #[test]
189 fn merge_is_idempotent() {
190 let mut s1 = GSet::new();
191 s1.insert(1);
192
193 let mut s2 = GSet::new();
194 s2.insert(2);
195
196 s1.merge(&s2);
197 let after_first = s1.clone();
198 s1.merge(&s2);
199
200 assert_eq!(s1, after_first);
201 }
202
203 #[test]
204 fn delta_apply_equivalent_to_merge() {
205 let mut s1 = GSet::new();
206 s1.insert(1);
207 s1.insert(2);
208 s1.insert(3);
209
210 let mut s2 = GSet::new();
211 s2.insert(2);
212 s2.insert(4);
213
214 let mut full = s2.clone();
215 full.merge(&s1);
216
217 let mut via_delta = s2.clone();
218 let d = s1.delta(&s2);
219 via_delta.apply_delta(&d);
220
221 assert_eq!(full, via_delta);
222 }
223
224 #[test]
225 fn delta_is_empty_when_equal() {
226 let mut s1 = GSet::new();
227 s1.insert(1);
228 s1.insert(2);
229
230 let s2 = s1.clone();
231 let d = s1.delta(&s2);
232 assert!(d.elements.is_empty());
233 }
234
235 #[test]
236 fn from_iterator() {
237 let s: GSet<i32> = vec![1, 2, 3].into_iter().collect();
238 assert_eq!(s.len(), 3);
239 }
240}