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}