1pub mod crdt;
65pub mod document;
66pub mod error;
67pub mod presence;
68pub mod session;
69pub mod sync;
70
71#[cfg(feature = "text")]
72pub mod text;
73
74pub use crdt::*;
75pub use document::*;
76pub use error::*;
77pub use presence::*;
78pub use session::*;
79pub use sync::*;
80
81#[cfg(feature = "text")]
82pub use text::*;
83
84use serde::{Deserialize, Serialize};
85use uuid::Uuid;
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
89pub struct ReplicaId(pub Uuid);
90
91impl ReplicaId {
92 pub fn new() -> Self {
94 Self(Uuid::new_v4())
95 }
96
97 pub fn from_uuid(uuid: Uuid) -> Self {
99 Self(uuid)
100 }
101}
102
103impl Default for ReplicaId {
104 fn default() -> Self {
105 Self::new()
106 }
107}
108
109impl std::fmt::Display for ReplicaId {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "{}", self.0)
112 }
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
117pub struct LogicalClock {
118 pub counter: u64,
120 pub replica: ReplicaId,
122}
123
124impl LogicalClock {
125 pub fn new(counter: u64, replica: ReplicaId) -> Self {
127 Self { counter, replica }
128 }
129
130 pub fn tick(&mut self) -> Self {
132 self.counter += 1;
133 *self
134 }
135
136 pub fn merge(&mut self, other: &Self) {
138 self.counter = self.counter.max(other.counter);
139 }
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144pub struct VectorClock {
145 clocks: std::collections::HashMap<ReplicaId, u64>,
146}
147
148impl VectorClock {
149 pub fn new() -> Self {
151 Self {
152 clocks: std::collections::HashMap::new(),
153 }
154 }
155
156 pub fn increment(&mut self, replica: ReplicaId) -> u64 {
158 let counter = self.clocks.entry(replica).or_insert(0);
159 *counter += 1;
160 *counter
161 }
162
163 pub fn get(&self, replica: &ReplicaId) -> u64 {
165 *self.clocks.get(replica).unwrap_or(&0)
166 }
167
168 pub fn merge(&mut self, other: &Self) {
170 for (replica, counter) in &other.clocks {
171 let entry = self.clocks.entry(*replica).or_insert(0);
172 *entry = (*entry).max(*counter);
173 }
174 }
175
176 pub fn is_concurrent(&self, other: &Self) -> bool {
178 !self.happens_before(other) && !other.happens_before(self)
179 }
180
181 pub fn happens_before(&self, other: &Self) -> bool {
183 let mut dominated = false;
184 for (replica, &counter) in &self.clocks {
185 let other_counter = other.get(replica);
186 if counter > other_counter {
187 return false;
188 }
189 if counter < other_counter {
190 dominated = true;
191 }
192 }
193 for replica in other.clocks.keys() {
195 if !self.clocks.contains_key(replica) && other.get(replica) > 0 {
196 dominated = true;
197 }
198 }
199 dominated
200 }
201}
202
203impl Default for VectorClock {
204 fn default() -> Self {
205 Self::new()
206 }
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct Operation<T> {
212 pub id: Uuid,
214 pub replica: ReplicaId,
216 pub timestamp: LogicalClock,
218 pub data: T,
220 pub deps: Vec<Uuid>,
222}
223
224impl<T> Operation<T> {
225 pub fn new(replica: ReplicaId, timestamp: LogicalClock, data: T) -> Self {
227 Self {
228 id: Uuid::new_v4(),
229 replica,
230 timestamp,
231 data,
232 deps: Vec::new(),
233 }
234 }
235
236 pub fn with_dep(mut self, dep: Uuid) -> Self {
238 self.deps.push(dep);
239 self
240 }
241
242 pub fn with_deps(mut self, deps: impl IntoIterator<Item = Uuid>) -> Self {
244 self.deps.extend(deps);
245 self
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252
253 #[test]
254 fn test_replica_id() {
255 let id1 = ReplicaId::new();
256 let id2 = ReplicaId::new();
257 assert_ne!(id1, id2);
258 }
259
260 #[test]
261 fn test_logical_clock() {
262 let replica = ReplicaId::new();
263 let mut clock = LogicalClock::new(0, replica);
264
265 assert_eq!(clock.counter, 0);
266 clock.tick();
267 assert_eq!(clock.counter, 1);
268 }
269
270 #[test]
271 fn test_vector_clock() {
272 let replica1 = ReplicaId::new();
273 let replica2 = ReplicaId::new();
274
275 let mut vc1 = VectorClock::new();
276 vc1.increment(replica1);
277 vc1.increment(replica1);
278
279 let mut vc2 = VectorClock::new();
280 vc2.increment(replica2);
281
282 assert!(vc1.is_concurrent(&vc2));
283
284 vc1.merge(&vc2);
285 assert_eq!(vc1.get(&replica1), 2);
286 assert_eq!(vc1.get(&replica2), 1);
287 }
288
289 #[test]
290 fn test_happens_before() {
291 let replica = ReplicaId::new();
292
293 let mut vc1 = VectorClock::new();
294 vc1.increment(replica);
295
296 let mut vc2 = vc1.clone();
297 vc2.increment(replica);
298
299 assert!(vc1.happens_before(&vc2));
300 assert!(!vc2.happens_before(&vc1));
301 }
302}
303