1use crate::crdt::{CRDT, Mergeable, ReplicaId};
10use serde::{Deserialize, Serialize};
11use std::collections::{HashMap, BTreeMap, HashSet};
12use std::error::Error;
13use std::fmt;
14use uuid::Uuid;
15
16#[derive(Debug, Clone, PartialEq)]
18pub enum AdvancedCrdtError {
19 InvalidPosition(String),
21 ElementNotFound(String),
23 InvalidRelationship(String),
25 CycleDetected(String),
27 InvalidOperation(String),
29 MergeError(String),
31}
32
33impl fmt::Display for AdvancedCrdtError {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 match self {
36 AdvancedCrdtError::InvalidPosition(msg) => write!(f, "Invalid position: {}", msg),
37 AdvancedCrdtError::ElementNotFound(msg) => write!(f, "Element not found: {}", msg),
38 AdvancedCrdtError::InvalidRelationship(msg) => write!(f, "Invalid relationship: {}", msg),
39 AdvancedCrdtError::CycleDetected(msg) => write!(f, "Cycle detected: {}", msg),
40 AdvancedCrdtError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
41 AdvancedCrdtError::MergeError(msg) => write!(f, "Merge error: {}", msg),
42 }
43 }
44}
45
46impl Error for AdvancedCrdtError {}
47
48#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
50pub struct PositionId {
51 pub replica_id: ReplicaId,
53 pub timestamp: u64,
55 pub disambiguation: u64,
57}
58
59impl PositionId {
60 pub fn new(replica_id: ReplicaId, timestamp: u64, disambiguation: u64) -> Self {
62 Self {
63 replica_id,
64 timestamp,
65 disambiguation,
66 }
67 }
68}
69
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72pub struct RgaElement<T> {
73 pub position: PositionId,
75 pub value: T,
77 pub visible: bool,
79 pub prev: Option<PositionId>,
81}
82
83impl<T> RgaElement<T> {
84 pub fn new(position: PositionId, value: T, prev: Option<PositionId>) -> Self {
86 Self {
87 position,
88 value,
89 visible: true,
90 prev,
91 }
92 }
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub struct Rga<T> {
98 replica_id: ReplicaId,
100 elements: HashMap<PositionId, RgaElement<T>>,
102 timestamp_counter: u64,
104 disambiguation_counter: u64,
106}
107
108impl<T: Clone + PartialEq> Rga<T> {
109 pub fn new(replica_id: ReplicaId) -> Self {
111 Self {
112 replica_id,
113 elements: HashMap::new(),
114 timestamp_counter: 0,
115 disambiguation_counter: 0,
116 }
117 }
118
119 pub fn insert_after(&mut self, value: T, after: Option<PositionId>) -> Result<PositionId, AdvancedCrdtError> {
121 self.timestamp_counter += 1;
122 self.disambiguation_counter += 1;
123
124 let position = PositionId::new(
125 self.replica_id.clone(),
126 self.timestamp_counter,
127 self.disambiguation_counter,
128 );
129
130 let element = RgaElement::new(position.clone(), value, after);
131 self.elements.insert(position.clone(), element);
132
133 Ok(position)
134 }
135
136 pub fn delete(&mut self, position: &PositionId) -> Result<(), AdvancedCrdtError> {
138 if let Some(element) = self.elements.get_mut(position) {
139 element.visible = false;
140 Ok(())
141 } else {
142 Err(AdvancedCrdtError::ElementNotFound(format!("Position {:?}", position)))
143 }
144 }
145
146 pub fn to_vec(&self) -> Vec<T> {
148 let mut result = Vec::new();
149
150 let mut elements: Vec<_> = self.elements.values()
153 .filter(|e| e.visible)
154 .collect();
155
156 elements.sort_by(|a, b| a.position.cmp(&b.position));
158
159 for element in elements {
161 result.push(element.value.clone());
162 }
163
164 result
165 }
166
167 fn find_first_element(&self) -> Option<PositionId> {
169 self.elements.values()
171 .find(|e| e.prev.is_none())
172 .map(|e| e.position.clone())
173 }
174
175 fn find_next_element(&self, position: &PositionId) -> Option<PositionId> {
177 self.elements.values()
178 .find(|e| e.prev.as_ref() == Some(position))
179 .map(|e| e.position.clone())
180 }
181
182 pub fn len(&self) -> usize {
184 self.elements.len()
185 }
186
187 pub fn is_empty(&self) -> bool {
189 self.elements.is_empty()
190 }
191}
192
193impl<T: Clone + PartialEq> CRDT for Rga<T> {
194 fn replica_id(&self) -> &ReplicaId {
195 &self.replica_id
196 }
197}
198
199impl<T: Clone + PartialEq + Send + Sync> Mergeable for Rga<T> {
200 type Error = AdvancedCrdtError;
201
202 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
203 for (position, other_element) in &other.elements {
205 if let Some(self_element) = self.elements.get_mut(position) {
206 if other_element.position.timestamp > self_element.position.timestamp {
208 *self_element = other_element.clone();
209 }
210 } else {
211 self.elements.insert(position.clone(), other_element.clone());
213 }
214 }
215
216 Ok(())
217 }
218
219 fn has_conflict(&self, other: &Self) -> bool {
220 for (position, self_element) in &self.elements {
222 if let Some(other_element) = other.elements.get(position) {
223 if self_element.value != other_element.value {
224 return true;
225 }
226 }
227 }
228 false
229 }
230}
231
232#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
234pub struct LseqElement<T> {
235 pub position: PositionId,
237 pub value: T,
239 pub visible: bool,
241}
242
243impl<T> LseqElement<T> {
244 pub fn new(position: PositionId, value: T) -> Self {
246 Self {
247 position,
248 value,
249 visible: true,
250 }
251 }
252}
253
254#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
256pub struct Lseq<T> {
257 replica_id: ReplicaId,
259 elements: BTreeMap<PositionId, LseqElement<T>>,
261 timestamp_counter: u64,
263 disambiguation_counter: u64,
265}
266
267impl<T: Clone + PartialEq> Lseq<T> {
268 pub fn new(replica_id: ReplicaId) -> Self {
270 Self {
271 replica_id,
272 elements: BTreeMap::new(),
273 timestamp_counter: 0,
274 disambiguation_counter: 0,
275 }
276 }
277
278 pub fn insert(&mut self, value: T, _position: Option<PositionId>) -> Result<PositionId, AdvancedCrdtError> {
280 self.timestamp_counter += 1;
281 self.disambiguation_counter += 1;
282
283 let new_position = PositionId::new(
284 self.replica_id.clone(),
285 self.timestamp_counter,
286 self.disambiguation_counter,
287 );
288
289 let element = LseqElement::new(new_position.clone(), value);
290 self.elements.insert(new_position.clone(), element);
291
292 Ok(new_position)
293 }
294
295 pub fn delete(&mut self, position: &PositionId) -> Result<(), AdvancedCrdtError> {
297 if let Some(element) = self.elements.get_mut(position) {
298 element.visible = false;
299 Ok(())
300 } else {
301 Err(AdvancedCrdtError::ElementNotFound(format!("Position {:?}", position)))
302 }
303 }
304
305 pub fn to_vec(&self) -> Vec<T> {
307 self.elements.values()
308 .filter(|e| e.visible)
309 .map(|e| e.value.clone())
310 .collect()
311 }
312
313 pub fn len(&self) -> usize {
315 self.elements.len()
316 }
317
318 pub fn is_empty(&self) -> bool {
320 self.elements.is_empty()
321 }
322
323 pub fn get_elements(&self) -> &BTreeMap<PositionId, LseqElement<T>> {
325 &self.elements
326 }
327}
328
329impl<T: Clone + PartialEq> CRDT for Lseq<T> {
330 fn replica_id(&self) -> &ReplicaId {
331 &self.replica_id
332 }
333}
334
335impl<T: Clone + PartialEq + Send + Sync> Mergeable for Lseq<T> {
336 type Error = AdvancedCrdtError;
337
338 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
339 for (position, other_element) in &other.elements {
341 if let Some(self_element) = self.elements.get_mut(position) {
342 if other_element.position.timestamp > self_element.position.timestamp {
344 *self_element = other_element.clone();
345 }
346 } else {
347 self.elements.insert(position.clone(), other_element.clone());
349 }
350 }
351
352 Ok(())
353 }
354
355 fn has_conflict(&self, other: &Self) -> bool {
356 for (position, self_element) in &self.elements {
358 if let Some(other_element) = other.elements.get(position) {
359 if self_element.value != other_element.value {
360 return true;
361 }
362 }
363 }
364 false
365 }
366}
367
368#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
370pub struct YjsNode<T> {
371 pub id: PositionId,
373 pub value: T,
375 pub parent: Option<PositionId>,
377 pub children: Vec<PositionId>,
379 pub visible: bool,
381}
382
383impl<T> YjsNode<T> {
384 pub fn new(id: PositionId, value: T, parent: Option<PositionId>) -> Self {
386 Self {
387 id,
388 value,
389 parent,
390 children: Vec::new(),
391 visible: true,
392 }
393 }
394}
395
396#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
398pub struct YjsTree<T> {
399 replica_id: ReplicaId,
401 nodes: HashMap<PositionId, YjsNode<T>>,
403 root: Option<PositionId>,
405 timestamp_counter: u64,
407 disambiguation_counter: u64,
409}
410
411impl<T: Clone + PartialEq> YjsTree<T> {
412 pub fn new(replica_id: ReplicaId) -> Self {
414 Self {
415 replica_id,
416 nodes: HashMap::new(),
417 root: None,
418 timestamp_counter: 0,
419 disambiguation_counter: 0,
420 }
421 }
422
423 pub fn add_root(&mut self, value: T) -> Result<PositionId, AdvancedCrdtError> {
425 self.timestamp_counter += 1;
426 self.disambiguation_counter += 1;
427
428 let id = PositionId::new(
429 self.replica_id.clone(),
430 self.timestamp_counter,
431 self.disambiguation_counter,
432 );
433
434 let node = YjsNode::new(id.clone(), value, None);
435 self.nodes.insert(id.clone(), node);
436 self.root = Some(id.clone());
437
438 Ok(id)
439 }
440
441 pub fn add_child(&mut self, parent_id: &PositionId, value: T) -> Result<PositionId, AdvancedCrdtError> {
443 if !self.nodes.contains_key(parent_id) {
444 return Err(AdvancedCrdtError::ElementNotFound(format!("Parent {:?}", parent_id)));
445 }
446
447 self.timestamp_counter += 1;
448 self.disambiguation_counter += 1;
449
450 let id = PositionId::new(
451 self.replica_id.clone(),
452 self.timestamp_counter,
453 self.disambiguation_counter,
454 );
455
456 let node = YjsNode::new(id.clone(), value, Some(parent_id.clone()));
457 self.nodes.insert(id.clone(), node);
458
459 if let Some(parent) = self.nodes.get_mut(parent_id) {
461 parent.children.push(id.clone());
462 }
463
464 Ok(id)
465 }
466
467 pub fn delete(&mut self, node_id: &PositionId) -> Result<(), AdvancedCrdtError> {
469 if let Some(node) = self.nodes.get_mut(node_id) {
470 node.visible = false;
471 Ok(())
472 } else {
473 Err(AdvancedCrdtError::ElementNotFound(format!("Node {:?}", node_id)))
474 }
475 }
476
477 pub fn to_tree(&self) -> Option<YjsTreeNode<T>> {
479 if let Some(root_id) = &self.root {
480 self.build_tree_node(root_id)
481 } else {
482 None
483 }
484 }
485
486 fn build_tree_node(&self, node_id: &PositionId) -> Option<YjsTreeNode<T>> {
488 if let Some(node) = self.nodes.get(node_id) {
489 if !node.visible {
490 return None;
491 }
492
493 let children: Vec<YjsTreeNode<T>> = node.children
494 .iter()
495 .filter_map(|child_id| self.build_tree_node(child_id))
496 .collect();
497
498 Some(YjsTreeNode {
499 id: node.id.clone(),
500 value: node.value.clone(),
501 children,
502 })
503 } else {
504 None
505 }
506 }
507
508 pub fn len(&self) -> usize {
510 self.nodes.len()
511 }
512
513 pub fn is_empty(&self) -> bool {
515 self.nodes.is_empty()
516 }
517}
518
519#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
521pub struct YjsTreeNode<T> {
522 pub id: PositionId,
524 pub value: T,
526 pub children: Vec<YjsTreeNode<T>>,
528}
529
530impl<T: Clone + PartialEq> CRDT for YjsTree<T> {
531 fn replica_id(&self) -> &ReplicaId {
532 &self.replica_id
533 }
534}
535
536impl<T: Clone + PartialEq + Send + Sync> Mergeable for YjsTree<T> {
537 type Error = AdvancedCrdtError;
538
539 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
540 for (node_id, other_node) in &other.nodes {
542 if let Some(self_node) = self.nodes.get_mut(node_id) {
543 if other_node.id.timestamp > self_node.id.timestamp {
545 *self_node = other_node.clone();
546 }
547 } else {
548 self.nodes.insert(node_id.clone(), other_node.clone());
550 }
551 }
552
553 if let Some(other_root) = &other.root {
555 if self.root.is_none() {
556 self.root = Some(other_root.clone());
557 } else if let Some(self_root) = &self.root {
558 if let (Some(other_root_node), Some(self_root_node)) = (
559 other.nodes.get(other_root),
560 self.nodes.get(self_root)
561 ) {
562 if other_root_node.id.timestamp > self_root_node.id.timestamp {
563 self.root = Some(other_root.clone());
564 }
565 }
566 }
567 }
568
569 Ok(())
570 }
571
572 fn has_conflict(&self, other: &Self) -> bool {
573 for (node_id, self_node) in &self.nodes {
575 if let Some(other_node) = other.nodes.get(node_id) {
576 if self_node.value != other_node.value {
577 return true;
578 }
579 }
580 }
581 false
582 }
583}
584
585#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
587pub struct DagNode<T> {
588 pub id: PositionId,
590 pub value: T,
592 pub incoming: HashSet<PositionId>,
594 pub outgoing: HashSet<PositionId>,
596 pub visible: bool,
598}
599
600impl<T> DagNode<T> {
601 pub fn new(id: PositionId, value: T) -> Self {
603 Self {
604 id,
605 value,
606 incoming: HashSet::new(),
607 outgoing: HashSet::new(),
608 visible: true,
609 }
610 }
611}
612
613#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
615pub struct Dag<T> {
616 replica_id: ReplicaId,
618 nodes: HashMap<PositionId, DagNode<T>>,
620 timestamp_counter: u64,
622 disambiguation_counter: u64,
624}
625
626impl<T: Clone + PartialEq> Dag<T> {
627 pub fn new(replica_id: ReplicaId) -> Self {
629 Self {
630 replica_id,
631 nodes: HashMap::new(),
632 timestamp_counter: 0,
633 disambiguation_counter: 0,
634 }
635 }
636
637 pub fn add_node(&mut self, value: T) -> Result<PositionId, AdvancedCrdtError> {
639 self.timestamp_counter += 1;
640 self.disambiguation_counter += 1;
641
642 let id = PositionId::new(
643 self.replica_id.clone(),
644 self.timestamp_counter,
645 self.disambiguation_counter,
646 );
647
648 let node = DagNode::new(id.clone(), value);
649 self.nodes.insert(id.clone(), node);
650
651 Ok(id)
652 }
653
654 pub fn add_edge(&mut self, from: &PositionId, to: &PositionId) -> Result<(), AdvancedCrdtError> {
656 if !self.nodes.contains_key(from) || !self.nodes.contains_key(to) {
657 return Err(AdvancedCrdtError::ElementNotFound("Node not found".to_string()));
658 }
659
660 if self.would_create_cycle(from, to) {
662 return Err(AdvancedCrdtError::CycleDetected("Adding edge would create cycle".to_string()));
663 }
664
665 if let Some(from_node) = self.nodes.get_mut(from) {
667 from_node.outgoing.insert(to.clone());
668 }
669 if let Some(to_node) = self.nodes.get_mut(to) {
670 to_node.incoming.insert(from.clone());
671 }
672
673 Ok(())
674 }
675
676 pub fn remove_edge(&mut self, from: &PositionId, to: &PositionId) -> Result<(), AdvancedCrdtError> {
678 if let Some(from_node) = self.nodes.get_mut(from) {
679 from_node.outgoing.remove(to);
680 }
681 if let Some(to_node) = self.nodes.get_mut(to) {
682 to_node.incoming.remove(from);
683 }
684
685 Ok(())
686 }
687
688 pub fn delete_node(&mut self, node_id: &PositionId) -> Result<(), AdvancedCrdtError> {
690 if let Some(node) = self.nodes.get(node_id) {
691 let incoming_edges = node.incoming.clone();
692 let outgoing_edges = node.outgoing.clone();
693
694 if let Some(node) = self.nodes.get_mut(node_id) {
696 node.visible = false;
697 }
698
699 for incoming in &incoming_edges {
701 if let Some(incoming_node) = self.nodes.get_mut(incoming) {
702 incoming_node.outgoing.remove(node_id);
703 }
704 }
705 for outgoing in &outgoing_edges {
706 if let Some(outgoing_node) = self.nodes.get_mut(outgoing) {
707 outgoing_node.incoming.remove(node_id);
708 }
709 }
710
711 Ok(())
712 } else {
713 Err(AdvancedCrdtError::ElementNotFound(format!("Node {:?}", node_id)))
714 }
715 }
716
717 fn would_create_cycle(&self, from: &PositionId, to: &PositionId) -> bool {
719 if from == to {
720 return true;
721 }
722
723 let mut visited = HashSet::new();
725 self.dfs_cycle_check(to, from, &mut visited)
726 }
727
728 fn dfs_cycle_check(&self, current: &PositionId, target: &PositionId, visited: &mut HashSet<PositionId>) -> bool {
730 if current == target {
731 return true;
732 }
733
734 if visited.contains(current) {
735 return false;
736 }
737
738 visited.insert(current.clone());
739
740 if let Some(node) = self.nodes.get(current) {
741 for next in &node.outgoing {
742 if self.dfs_cycle_check(next, target, visited) {
743 return true;
744 }
745 }
746 }
747
748 false
749 }
750
751 pub fn topological_sort(&self) -> Vec<PositionId> {
753 let mut result = Vec::new();
754 let mut visited = HashSet::new();
755
756 for node_id in self.nodes.keys() {
757 if !visited.contains(node_id) {
758 self.dfs_topological(node_id, &mut visited, &mut result);
759 }
760 }
761
762 result.reverse();
763 result
764 }
765
766 fn dfs_topological(&self, node_id: &PositionId, visited: &mut HashSet<PositionId>, result: &mut Vec<PositionId>) {
768 if visited.contains(node_id) {
769 return;
770 }
771
772 visited.insert(node_id.clone());
773
774 if let Some(node) = self.nodes.get(node_id) {
775 for next in &node.outgoing {
776 self.dfs_topological(next, visited, result);
777 }
778 }
779
780 result.push(node_id.clone());
781 }
782
783 pub fn len(&self) -> usize {
785 self.nodes.len()
786 }
787
788 pub fn is_empty(&self) -> bool {
790 self.nodes.is_empty()
791 }
792
793 pub fn get_nodes(&self) -> &HashMap<PositionId, DagNode<T>> {
795 &self.nodes
796 }
797}
798
799impl<T: Clone + PartialEq> CRDT for Dag<T> {
800 fn replica_id(&self) -> &ReplicaId {
801 &self.replica_id
802 }
803}
804
805impl<T: Clone + PartialEq + Send + Sync> Mergeable for Dag<T> {
806 type Error = AdvancedCrdtError;
807
808 fn merge(&mut self, other: &Self) -> Result<(), Self::Error> {
809 for (node_id, other_node) in &other.nodes {
811 if let Some(self_node) = self.nodes.get_mut(node_id) {
812 if other_node.id.timestamp > self_node.id.timestamp {
814 *self_node = other_node.clone();
815 }
816 } else {
817 self.nodes.insert(node_id.clone(), other_node.clone());
819 }
820 }
821
822 Ok(())
823 }
824
825 fn has_conflict(&self, other: &Self) -> bool {
826 for (node_id, self_node) in &self.nodes {
828 if let Some(other_node) = other.nodes.get(node_id) {
829 if self_node.value != other_node.value {
830 return true;
831 }
832 }
833 }
834 false
835 }
836}
837
838#[cfg(test)]
839mod tests {
840 use super::*;
841 use crate::crdt::ReplicaId;
842 use uuid::Uuid;
843
844 fn create_replica(id: u64) -> ReplicaId {
845 ReplicaId::from(Uuid::from_u64_pair(0, id))
846 }
847
848 #[test]
849 fn test_rga_creation() {
850 let replica_id = create_replica(1);
851 let rga = Rga::<String>::new(replica_id.clone());
852
853 assert_eq!(rga.replica_id(), &replica_id);
854 assert!(rga.is_empty());
855 assert_eq!(rga.len(), 0);
856 }
857
858 #[test]
859 fn test_rga_insert_and_delete() {
860 let replica_id = create_replica(1);
861 let mut rga = Rga::<String>::new(replica_id);
862
863 let pos1 = rga.insert_after("hello".to_string(), None).unwrap();
865 let pos2 = rga.insert_after("world".to_string(), Some(pos1.clone())).unwrap();
866 let pos3 = rga.insert_after("!".to_string(), Some(pos2.clone())).unwrap();
867
868 assert_eq!(rga.len(), 3);
869 assert_eq!(rga.to_vec(), vec!["hello", "world", "!"]);
870
871 rga.delete(&pos2).unwrap();
873 assert_eq!(rga.to_vec(), vec!["hello", "!"]);
874
875 rga.delete(&pos1).unwrap();
877 assert_eq!(rga.to_vec(), vec!["!"]);
878
879 rga.delete(&pos3).unwrap();
881 assert_eq!(rga.to_vec(), Vec::<String>::new());
882 }
883
884 #[test]
885 fn test_rga_merge() {
886 let replica_id1 = create_replica(1);
887 let replica_id2 = create_replica(2);
888
889 let mut rga1 = Rga::<String>::new(replica_id1);
890 let mut rga2 = Rga::<String>::new(replica_id2);
891
892 let _pos1 = rga1.insert_after("hello".to_string(), None).unwrap();
894 let _pos2 = rga2.insert_after("world".to_string(), None).unwrap();
895
896 rga1.merge(&rga2).unwrap();
898
899 let elements = rga1.to_vec();
901 assert!(elements.contains(&"hello".to_string()));
902 assert!(elements.contains(&"world".to_string()));
903 }
904
905 #[test]
906 fn test_lseq_creation() {
907 let replica_id = create_replica(1);
908 let lseq = Lseq::<String>::new(replica_id.clone());
909
910 assert_eq!(lseq.replica_id(), &replica_id);
911 assert!(lseq.is_empty());
912 assert_eq!(lseq.len(), 0);
913 }
914
915 #[test]
916 fn test_lseq_insert_and_delete() {
917 let replica_id = create_replica(1);
918 let mut lseq = Lseq::<String>::new(replica_id);
919
920 let pos1 = lseq.insert("hello".to_string(), None).unwrap();
922 let pos2 = lseq.insert("world".to_string(), None).unwrap();
923 let pos3 = lseq.insert("!".to_string(), None).unwrap();
924
925 assert_eq!(lseq.len(), 3);
926 let elements = lseq.to_vec();
927 assert!(elements.contains(&"hello".to_string()));
928 assert!(elements.contains(&"world".to_string()));
929 assert!(elements.contains(&"!".to_string()));
930
931 lseq.delete(&pos2).unwrap();
933 let elements = lseq.to_vec();
934 assert!(elements.contains(&"hello".to_string()));
935 assert!(!elements.contains(&"world".to_string()));
936 assert!(elements.contains(&"!".to_string()));
937 }
938
939 #[test]
940 fn test_lseq_merge() {
941 let replica_id1 = create_replica(1);
942 let replica_id2 = create_replica(2);
943
944 let mut lseq1 = Lseq::<String>::new(replica_id1);
945 let mut lseq2 = Lseq::<String>::new(replica_id2);
946
947 lseq1.insert("hello".to_string(), None).unwrap();
949 lseq2.insert("world".to_string(), None).unwrap();
950
951 lseq1.merge(&lseq2).unwrap();
953
954 let elements = lseq1.to_vec();
956 assert!(elements.contains(&"hello".to_string()));
957 assert!(elements.contains(&"world".to_string()));
958 }
959
960 #[test]
961 fn test_yjs_tree_creation() {
962 let replica_id = create_replica(1);
963 let tree = YjsTree::<String>::new(replica_id.clone());
964
965 assert_eq!(tree.replica_id(), &replica_id);
966 assert!(tree.is_empty());
967 assert_eq!(tree.len(), 0);
968 }
969
970 #[test]
971 fn test_yjs_tree_operations() {
972 let replica_id = create_replica(1);
973 let mut tree = YjsTree::<String>::new(replica_id);
974
975 let root_id = tree.add_root("root".to_string()).unwrap();
977 assert_eq!(tree.len(), 1);
978
979 let child1_id = tree.add_child(&root_id, "child1".to_string()).unwrap();
981 let child2_id = tree.add_child(&root_id, "child2".to_string()).unwrap();
982 assert_eq!(tree.len(), 3);
983
984 let grandchild_id = tree.add_child(&child1_id, "grandchild".to_string()).unwrap();
986 assert_eq!(tree.len(), 4);
987
988 tree.delete(&child2_id).unwrap();
990 assert_eq!(tree.len(), 4); let tree_structure = tree.to_tree().unwrap();
994 assert_eq!(tree_structure.value, "root");
995 assert_eq!(tree_structure.children.len(), 1); assert_eq!(tree_structure.children[0].value, "child1");
997 assert_eq!(tree_structure.children[0].children.len(), 1);
998 assert_eq!(tree_structure.children[0].children[0].value, "grandchild");
999 }
1000
1001 #[test]
1002 fn test_yjs_tree_merge() {
1003 let replica_id1 = create_replica(1);
1004 let replica_id2 = create_replica(2);
1005
1006 let mut tree1 = YjsTree::<String>::new(replica_id1);
1007 let mut tree2 = YjsTree::<String>::new(replica_id2);
1008
1009 let root1_id = tree1.add_root("root1".to_string()).unwrap();
1011 let root2_id = tree2.add_root("root2".to_string()).unwrap();
1012
1013 tree1.add_child(&root1_id, "child1".to_string()).unwrap();
1015 tree2.add_child(&root2_id, "child2".to_string()).unwrap();
1016
1017 tree1.merge(&tree2).unwrap();
1019
1020 assert_eq!(tree1.len(), 4); }
1023
1024 #[test]
1025 fn test_dag_creation() {
1026 let replica_id = create_replica(1);
1027 let dag = Dag::<String>::new(replica_id.clone());
1028
1029 assert_eq!(dag.replica_id(), &replica_id);
1030 assert!(dag.is_empty());
1031 assert_eq!(dag.len(), 0);
1032 }
1033
1034 #[test]
1035 fn test_dag_operations() {
1036 let replica_id = create_replica(1);
1037 let mut dag = Dag::<String>::new(replica_id);
1038
1039 let node1_id = dag.add_node("node1".to_string()).unwrap();
1041 let node2_id = dag.add_node("node2".to_string()).unwrap();
1042 let node3_id = dag.add_node("node3".to_string()).unwrap();
1043
1044 assert_eq!(dag.len(), 3);
1045
1046 dag.add_edge(&node1_id, &node2_id).unwrap();
1048 dag.add_edge(&node2_id, &node3_id).unwrap();
1049
1050 let sorted = dag.topological_sort();
1052 assert_eq!(sorted.len(), 3);
1053 assert_eq!(sorted[0], node1_id);
1054 assert_eq!(sorted[1], node2_id);
1055 assert_eq!(sorted[2], node3_id);
1056
1057 dag.remove_edge(&node1_id, &node2_id).unwrap();
1059
1060 dag.delete_node(&node2_id).unwrap();
1062 assert_eq!(dag.len(), 3); }
1064
1065 #[test]
1066 fn test_dag_cycle_detection() {
1067 let replica_id = create_replica(1);
1068 let mut dag = Dag::<String>::new(replica_id);
1069
1070 let node1_id = dag.add_node("node1".to_string()).unwrap();
1072 let node2_id = dag.add_node("node2".to_string()).unwrap();
1073 let node3_id = dag.add_node("node3".to_string()).unwrap();
1074
1075 dag.add_edge(&node1_id, &node2_id).unwrap();
1077 dag.add_edge(&node2_id, &node3_id).unwrap();
1078
1079 let result = dag.add_edge(&node3_id, &node1_id);
1081 assert!(result.is_err());
1082 assert_eq!(result.unwrap_err(), AdvancedCrdtError::CycleDetected("Adding edge would create cycle".to_string()));
1083 }
1084
1085 #[test]
1086 fn test_dag_merge() {
1087 let replica_id1 = create_replica(1);
1088 let replica_id2 = create_replica(2);
1089
1090 let mut dag1 = Dag::<String>::new(replica_id1);
1091 let mut dag2 = Dag::<String>::new(replica_id2);
1092
1093 let node1_id = dag1.add_node("node1".to_string()).unwrap();
1095 let node2_id = dag2.add_node("node2".to_string()).unwrap();
1096
1097 dag1.merge(&dag2).unwrap();
1102
1103 assert_eq!(dag1.len(), 2);
1105 }
1106
1107 #[test]
1108 fn test_advanced_crdt_traits() {
1109 let replica_id = create_replica(1);
1110
1111 let rga: Rga<String> = Rga::new(replica_id.clone());
1113 let lseq: Lseq<String> = Lseq::new(replica_id.clone());
1114 let tree: YjsTree<String> = YjsTree::new(replica_id.clone());
1115 let dag: Dag<String> = Dag::new(replica_id);
1116
1117 let _: &dyn CRDT = &rga;
1119 let _: &dyn CRDT = &lseq;
1120 let _: &dyn CRDT = &tree;
1121 let _: &dyn CRDT = &dag;
1122 }
1123}