safemesh_crdt/crdt/
enable_wins_flag.rs1use crate::{Crdt, MergeError, Mergeable, RecordId, WireError};
6use alloc::{collections::BTreeSet, vec::Vec};
7
8#[derive(Clone, Debug)]
10pub enum EnableWinsFlagDelta<K> {
11 Enable { token: K },
12 Disable { tokens: Vec<K> },
13}
14
15impl<K: Ord> PartialEq for EnableWinsFlagDelta<K> {
18 fn eq(&self, other: &Self) -> bool {
19 match (self, other) {
20 (Self::Enable { token: a }, Self::Enable { token: b }) => a == b,
21 (Self::Disable { tokens: a }, Self::Disable { tokens: b }) => {
22 a.iter().collect::<BTreeSet<_>>() == b.iter().collect::<BTreeSet<_>>()
23 }
24 _ => false,
25 }
26 }
27}
28
29impl<K: Ord> Eq for EnableWinsFlagDelta<K> {}
30
31#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct EnableWinsFlag<K: Ord> {
38 pub(super) enables: BTreeSet<K>,
39 pub(super) tombstones: BTreeSet<K>,
40}
41
42impl<K: Ord> EnableWinsFlag<K> {
43 pub fn new() -> Self {
44 EnableWinsFlag {
45 enables: BTreeSet::new(),
46 tombstones: BTreeSet::new(),
47 }
48 }
49
50 pub fn enable(&mut self, token: K) {
51 self.enables.insert(token);
52 }
53
54 pub fn disable<I>(&mut self, tokens: I)
55 where
56 I: IntoIterator<Item = K>,
57 {
58 self.tombstones.extend(tokens);
59 }
60
61 pub fn merge(&mut self, other: &Self)
62 where
63 K: Clone,
64 {
65 self.enables.extend(other.enables.iter().cloned());
66 self.tombstones.extend(other.tombstones.iter().cloned());
67 }
68
69 pub fn enables(&self) -> &BTreeSet<K> {
70 &self.enables
71 }
72
73 pub fn tombstones(&self) -> &BTreeSet<K> {
74 &self.tombstones
75 }
76}
77
78impl<K: Ord + Clone> EnableWinsFlag<K> {
79 pub fn observed_tokens(&self) -> BTreeSet<K> {
80 self.enables.iter().cloned().collect()
81 }
82
83 pub fn value(&self) -> bool {
84 self.enables
85 .iter()
86 .any(|token| !self.tombstones.contains(token))
87 }
88}
89
90impl<K: Ord> Default for EnableWinsFlag<K> {
91 fn default() -> Self {
92 Self::new()
93 }
94}
95
96impl<K: Ord + Clone> Mergeable for EnableWinsFlag<K> {
97 fn merge(&mut self, other: &Self) -> Result<(), MergeError> {
98 EnableWinsFlag::merge(self, other);
99 Ok(())
100 }
101}
102
103impl<K: Ord + Clone> Crdt for EnableWinsFlag<K> {
104 type Delta = EnableWinsFlagDelta<K>;
105
106 fn validate_record(&self, id: RecordId, _delta: &Self::Delta) -> Result<(), WireError> {
111 id.require_positive_sequence("Enable-wins flag")
112 }
113
114 fn apply_delta(&mut self, delta: Self::Delta) {
115 match delta {
116 EnableWinsFlagDelta::Enable { token } => self.enable(token),
117 EnableWinsFlagDelta::Disable { tokens } => self.disable(tokens),
118 }
119 }
120}