leptos_sync_core/crdt/basic/
replica_id.rs

1//! Replica ID type and utilities
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5use uuid::Uuid;
6
7/// Unique identifier for a replica
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9pub struct ReplicaId(#[serde(with = "uuid_serde")] pub Uuid);
10
11mod uuid_serde {
12    use super::*;
13    use serde::{Deserializer, Serializer};
14
15    pub fn serialize<S>(uuid: &Uuid, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        uuid.to_string().serialize(serializer)
20    }
21
22    pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
23    where
24        D: Deserializer<'de>,
25    {
26        let s = String::deserialize(deserializer)?;
27        Uuid::parse_str(&s).map_err(serde::de::Error::custom)
28    }
29}
30
31impl Default for ReplicaId {
32    fn default() -> Self {
33        Self(Uuid::new_v4())
34    }
35}
36
37impl fmt::Display for ReplicaId {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "{}", self.0)
40    }
41}
42
43impl From<Uuid> for ReplicaId {
44    fn from(uuid: Uuid) -> Self {
45        Self(uuid)
46    }
47}
48
49impl From<ReplicaId> for Uuid {
50    fn from(replica_id: ReplicaId) -> Self {
51        replica_id.0
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_replica_id_creation() {
61        let replica_id = ReplicaId::default();
62        assert_ne!(replica_id.0, Uuid::nil());
63    }
64
65    #[test]
66    fn test_replica_id_from_uuid() {
67        let uuid = Uuid::new_v4();
68        let replica_id = ReplicaId::from(uuid);
69        assert_eq!(replica_id.0, uuid);
70    }
71
72    #[test]
73    fn test_replica_id_serialization() {
74        let replica_id = ReplicaId::default();
75        let serialized = serde_json::to_string(&replica_id).unwrap();
76        let deserialized: ReplicaId = serde_json::from_str(&serialized).unwrap();
77        assert_eq!(replica_id, deserialized);
78    }
79
80    #[test]
81    fn test_replica_id_display() {
82        let replica_id = ReplicaId::default();
83        let display_str = format!("{}", replica_id);
84        assert!(!display_str.is_empty());
85    }
86
87    #[test]
88    fn test_replica_id_ordering() {
89        let uuid1 = Uuid::new_v4();
90        let uuid2 = Uuid::new_v4();
91        
92        let replica_id1 = ReplicaId::from(uuid1);
93        let replica_id2 = ReplicaId::from(uuid2);
94        
95        // Test that ordering is consistent
96        let result1 = replica_id1 < replica_id2;
97        let result2 = replica_id2 > replica_id1;
98        assert_eq!(result1, result2);
99    }
100}