crdts/gset.rs
1use core::convert::Infallible;
2use std::collections::BTreeSet;
3
4use serde::{Deserialize, Serialize};
5
6use crate::{CmRDT, CvRDT};
7
8/// A `GSet` is a grow-only set.
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct GSet<T: Ord> {
11 value: BTreeSet<T>,
12}
13
14impl<T: Ord> Default for GSet<T> {
15 fn default() -> Self {
16 GSet::new()
17 }
18}
19
20impl<T: Ord> From<GSet<T>> for BTreeSet<T> {
21 fn from(gset: GSet<T>) -> BTreeSet<T> {
22 gset.value
23 }
24}
25
26impl<T: Ord> CvRDT for GSet<T> {
27 type Validation = Infallible;
28
29 fn validate_merge(&self, _other: &Self) -> Result<(), Self::Validation> {
30 Ok(())
31 }
32
33 /// Merges another `GSet` into this one.
34 ///
35 /// # Examples
36 ///
37 /// ```rust
38 /// use crdts::{GSet, CvRDT, CmRDT};
39 /// let (mut a, mut b) = (GSet::new(), GSet::new());
40 /// a.insert(1);
41 /// b.insert(2);
42 /// a.merge(b);
43 /// assert!(a.contains(&1));
44 /// assert!(a.contains(&2));
45 /// ```
46 fn merge(&mut self, other: Self) {
47 other.value.into_iter().for_each(|e| self.insert(e))
48 }
49}
50
51impl<T: Ord> CmRDT for GSet<T> {
52 type Op = T;
53 type Validation = Infallible;
54
55 fn validate_op(&self, _op: &Self::Op) -> Result<(), Self::Validation> {
56 Ok(())
57 }
58
59 fn apply(&mut self, op: Self::Op) {
60 self.insert(op);
61 }
62}
63
64impl<T: Ord> GSet<T> {
65 /// Instantiates an empty `GSet`.
66 pub fn new() -> Self {
67 Self {
68 value: BTreeSet::new(),
69 }
70 }
71
72 /// Inserts an element into this `GSet`.
73 ///
74 /// # Examples
75 ///
76 /// ```rust
77 /// use crdts::GSet;
78 /// let mut a = GSet::new();
79 /// a.insert(1);
80 /// assert!(a.contains(&1));
81 /// ```
82 pub fn insert(&mut self, element: T) {
83 self.value.insert(element);
84 }
85
86 /// Returns `true` if the `GSet` contains the element.
87 ///
88 /// # Examples
89 ///
90 /// ```rust
91 /// use crdts::GSet;
92 /// let mut a = GSet::new();
93 /// a.insert(1);
94 /// assert!(a.contains(&1));
95 /// ```
96 pub fn contains(&self, element: &T) -> bool {
97 self.value.contains(element)
98 }
99
100 /// Returns the `BTreeSet` for this `GSet`.
101 ///
102 /// # Examples
103 ///
104 /// ```rust
105 /// use crdts::GSet;
106 /// use std::collections::BTreeSet;
107 /// let mut a = GSet::new();
108 /// let mut b = BTreeSet::new();
109 /// for i in 1..10 {
110 /// a.insert(i);
111 /// b.insert(i);
112 /// }
113 ///
114 /// assert_eq!(a.read(), b);
115 /// ```
116 pub fn read(&self) -> BTreeSet<T>
117 where
118 T: Clone,
119 {
120 self.value.clone()
121 }
122}