crdt_kit/events.rs
1//! Operation-based CRDT trait for event sourcing.
2//!
3//! Op-based CRDTs produce **operations** (events) that can be:
4//! - Persisted as an append-only event log
5//! - Broadcast to other replicas for synchronization
6//! - Replayed to reconstruct state
7//!
8//! This trait bridges the gap between CRDTs and event sourcing:
9//! each CRDT operation IS a domain event.
10
11use crate::Crdt;
12
13/// A CRDT that can express its mutations as discrete operations.
14///
15/// Unlike state-based CRDTs (which merge full state), op-based CRDTs
16/// exchange individual operations. Each operation is an event that
17/// can be persisted, broadcast, and replayed.
18///
19/// # Relationship to Event Sourcing
20///
21/// ```text
22/// Traditional Event Sourcing:
23/// Command → Validate → Event → Persist → Apply → State
24///
25/// CRDT Event Sourcing (this trait):
26/// Operation → apply_op() → State
27/// (No validation needed — CRDTs guarantee convergence)
28/// ```
29///
30/// # Example
31///
32/// ```
33/// use crdt_kit::events::OpCrdt;
34/// use crdt_kit::prelude::*;
35/// // OpCrdt implementors produce typed operations
36/// // that can be serialized and stored as events.
37/// ```
38pub trait OpCrdt: Crdt {
39 /// The operation type this CRDT produces.
40 ///
41 /// Operations must be serializable (for persistence and network transfer)
42 /// and deterministically applicable (for convergence).
43 type Op;
44
45 /// Apply an operation to the current state.
46 ///
47 /// This is the core function: it takes an operation (from local or remote)
48 /// and updates the CRDT state. For convergence, `apply_op` must be:
49 /// - **Commutative**: order of operations doesn't matter
50 /// - **Idempotent**: applying the same op twice has no additional effect
51 fn apply_op(&mut self, op: &Self::Op);
52}