leptos_sync_core/crdt/advanced/
mod.rs

1//! Advanced CRDT Types
2//!
3//! This module provides advanced CRDT implementations including:
4//! - RGA (Replicated Growable Array) for collaborative text editing
5//! - LSEQ (Logoot Sequence) for ordered sequences
6//! - Yjs-style trees for hierarchical data
7//! - DAG (Directed Acyclic Graph) for complex relationships
8
9pub mod common;
10pub mod rga;
11pub mod lseq;
12pub mod yjs_tree;
13pub mod dag;
14
15// Re-export main types for convenience
16pub use common::{PositionId, AdvancedCrdtError};
17pub use rga::{Rga, RgaElement};
18pub use lseq::{Lseq, LseqElement};
19pub use yjs_tree::{YjsTree, YjsNode, YjsTreeNode};
20pub use dag::{Dag, DagNode};
21
22#[cfg(test)]
23mod integration_tests {
24    use super::*;
25    use super::super::{ReplicaId, basic::traits::Mergeable};
26    use uuid::Uuid;
27    
28    fn create_replica(id: u64) -> ReplicaId {
29        ReplicaId::from(Uuid::from_u64_pair(0, id))
30    }
31    
32    #[test]
33    fn test_advanced_crdt_traits() {
34        let replica_id = create_replica(1);
35        
36        // Test that all advanced CRDT types implement the required traits
37        let rga: Rga<String> = Rga::new(replica_id.clone());
38        let lseq: Lseq<String> = Lseq::new(replica_id.clone());
39        let tree: YjsTree<String> = YjsTree::new(replica_id.clone());
40        let dag: Dag<String> = Dag::new(replica_id);
41        
42        // This should compile if all types implement CRDT trait
43        let _: &dyn super::super::CRDT = &rga;
44        let _: &dyn super::super::CRDT = &lseq;
45        let _: &dyn super::super::CRDT = &tree;
46        let _: &dyn super::super::CRDT = &dag;
47    }
48
49    #[test]
50    fn test_advanced_crdt_merge_integration() {
51        let replica_id1 = create_replica(1);
52        let replica_id2 = create_replica(2);
53        
54        // Test RGA merge
55        let mut rga1: Rga<String> = Rga::new(replica_id1.clone());
56        let mut rga2: Rga<String> = Rga::new(replica_id2.clone());
57        
58        let _pos1 = rga1.insert_after("hello".to_string(), None).unwrap();
59        let _pos2 = rga2.insert_after("world".to_string(), None).unwrap();
60        
61        rga1.merge(&rga2).unwrap();
62        let elements = rga1.to_vec();
63        assert!(elements.contains(&"hello".to_string()));
64        assert!(elements.contains(&"world".to_string()));
65        
66        // Test LSEQ merge
67        let mut lseq1 = Lseq::new(replica_id1.clone());
68        let mut lseq2 = Lseq::new(replica_id2.clone());
69        
70        lseq1.insert("item1".to_string(), None).unwrap();
71        lseq2.insert("item2".to_string(), None).unwrap();
72        
73        lseq1.merge(&lseq2).unwrap();
74        let elements = lseq1.to_vec();
75        assert!(elements.contains(&"item1".to_string()));
76        assert!(elements.contains(&"item2".to_string()));
77        
78        // Test Yjs Tree merge
79        let mut tree1 = YjsTree::new(replica_id1.clone());
80        let mut tree2 = YjsTree::new(replica_id2.clone());
81        
82        let root1_id = tree1.add_root("root1".to_string()).unwrap();
83        let root2_id = tree2.add_root("root2".to_string()).unwrap();
84        
85        tree1.add_child(&root1_id, "child1".to_string()).unwrap();
86        tree2.add_child(&root2_id, "child2".to_string()).unwrap();
87        
88        tree1.merge(&tree2).unwrap();
89        assert_eq!(tree1.len(), 4); // 2 roots + 2 children
90        
91        // Test DAG merge
92        let mut dag1 = Dag::new(replica_id1);
93        let mut dag2 = Dag::new(replica_id2);
94        
95        let node1_id = dag1.add_node("node1".to_string()).unwrap();
96        let node2_id = dag2.add_node("node2".to_string()).unwrap();
97        
98        // No edges needed for merge test
99        
100        dag1.merge(&dag2).unwrap();
101        assert_eq!(dag1.len(), 2);
102    }
103
104    #[test]
105    fn test_position_id_ordering() {
106        let replica1 = create_replica(1);
107        let replica2 = create_replica(2);
108        
109        let pos1 = PositionId::new(replica1, 100, 10);
110        let pos2 = PositionId::new(replica1, 200, 10);
111        let pos3 = PositionId::new(replica2, 100, 10);
112        
113        assert!(pos1 < pos2);
114        assert!(pos1 < pos3);
115        assert!(pos2 > pos3);
116    }
117
118    #[test]
119    fn test_error_handling() {
120        let replica = create_replica(1);
121        let mut rga: Rga<String> = Rga::new(replica);
122        
123        // Test invalid position error
124        let fake_pos = PositionId::new(create_replica(999), 1, 1);
125        let result = rga.delete(&fake_pos);
126        assert!(result.is_err());
127        assert!(matches!(result.unwrap_err(), AdvancedCrdtError::ElementNotFound(_)));
128    }
129}