Skip to main content

crdt_kit/
version.rs

1//! Versioned serialization for CRDTs.
2//!
3//! Every CRDT type can be serialized with a version envelope that enables
4//! transparent migration when schemas evolve.
5
6use core::fmt;
7
8/// Identifies the type of CRDT for the version envelope.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10#[repr(u8)]
11pub enum CrdtType {
12    /// Grow-only counter.
13    GCounter = 1,
14    /// Positive-negative counter.
15    PNCounter = 2,
16    /// Grow-only set.
17    GSet = 3,
18    /// Two-phase set.
19    TwoPSet = 4,
20    /// Last-writer-wins register.
21    LWWRegister = 5,
22    /// Multi-value register.
23    MVRegister = 6,
24    /// Observed-remove set.
25    ORSet = 7,
26    /// Replicated Growable Array.
27    Rga = 8,
28    /// Collaborative text.
29    TextCrdt = 9,
30}
31
32/// Trait for CRDT types that support versioned serialization.
33///
34/// Types implementing this trait can be serialized with a 3-byte version
35/// envelope, enabling automatic migration when data schemas change.
36pub trait Versioned: Sized {
37    /// Current schema version for this CRDT type's serialization format.
38    const CURRENT_VERSION: u8;
39
40    /// The CRDT type identifier for the envelope.
41    const CRDT_TYPE: CrdtType;
42}
43
44/// Error during versioned serialization.
45#[derive(Debug, Clone)]
46pub enum VersionError {
47    /// Serialization failed.
48    Serialize(alloc::string::String),
49    /// Deserialization failed.
50    Deserialize(alloc::string::String),
51}
52
53impl fmt::Display for VersionError {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::Serialize(msg) => write!(f, "serialization error: {msg}"),
57            Self::Deserialize(msg) => write!(f, "deserialization error: {msg}"),
58        }
59    }
60}