crdt_kit/crdt.rs
1/// Compact node identifier for CRDT replicas.
2///
3/// Uses `u64` instead of `String` to avoid heap allocations on every
4/// operation — critical for embedded/IoT targets where `alloc` is expensive.
5///
6/// # Example
7///
8/// ```
9/// use crdt_kit::prelude::*;
10///
11/// let mut c = GCounter::new(1); // NodeId = 1
12/// c.increment();
13/// assert_eq!(c.value(), 1);
14/// ```
15pub type NodeId = u64;
16
17/// Core trait that all CRDTs must implement.
18///
19/// A CRDT (Conflict-free Replicated Data Type) guarantees that concurrent
20/// updates on different replicas will converge to the same state after merging,
21/// without requiring coordination.
22///
23/// # Properties
24///
25/// All implementations must satisfy:
26/// - **Commutativity:** `a.merge(b) == b.merge(a)`
27/// - **Associativity:** `a.merge(b.merge(c)) == a.merge(b).merge(c)`
28/// - **Idempotency:** `a.merge(a) == a`
29pub trait Crdt {
30 /// Merge another replica's state into this one.
31 ///
32 /// After merging, `self` contains the least upper bound of both states.
33 /// This operation is commutative, associative, and idempotent.
34 fn merge(&mut self, other: &Self);
35}
36
37/// Extension trait for delta-state CRDTs.
38///
39/// Delta-state CRDTs can produce compact deltas representing only the
40/// changes between two states. This enables efficient synchronization:
41/// instead of transferring the full state, replicas exchange small deltas.
42///
43/// # Example
44///
45/// ```
46/// use crdt_kit::prelude::*;
47///
48/// let mut c1 = GCounter::new(1);
49/// c1.increment();
50/// c1.increment();
51///
52/// let mut c2 = GCounter::new(2);
53/// c2.increment();
54///
55/// // Generate a delta from c1 that c2 doesn't have
56/// let delta = c1.delta(&c2);
57///
58/// // Apply just the delta instead of full state merge
59/// c2.apply_delta(&delta);
60/// assert_eq!(c2.value(), 3); // both counts included
61/// ```
62pub trait DeltaCrdt: Crdt {
63 /// The type of delta produced by this CRDT.
64 type Delta;
65
66 /// Generate a delta containing changes in `self` that `other` does not have.
67 ///
68 /// The returned delta is the minimal set of information needed to bring
69 /// a replica at state `other` up to date with `self`.
70 fn delta(&self, other: &Self) -> Self::Delta;
71
72 /// Apply a delta to this replica's state.
73 ///
74 /// This is equivalent to merging the state that produced the delta,
75 /// but typically much more efficient in terms of data transferred.
76 fn apply_delta(&mut self, delta: &Self::Delta);
77}