leptos_sync_core/crdt/graph/
edge.rs

1//! Graph edge operations and types
2
3use super::vertex::{VertexId, GraphError};
4use super::super::ReplicaId;
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7
8/// Unique identifier for a graph edge
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct EdgeId {
11    /// Unique identifier for the edge
12    pub id: Uuid,
13    /// Replica that created the edge
14    pub replica: ReplicaId,
15}
16
17impl EdgeId {
18    /// Create a new edge ID
19    pub fn new(replica: ReplicaId) -> Self {
20        Self {
21            id: Uuid::new_v4(),
22            replica,
23        }
24    }
25
26    /// Create an edge ID from existing UUID and replica
27    pub fn from_parts(id: Uuid, replica: ReplicaId) -> Self {
28        Self { id, replica }
29    }
30}
31
32/// Metadata for a graph edge
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub struct EdgeMetadata {
35    /// When the edge was created
36    pub created_at: u64,
37    /// When the edge was last modified
38    pub modified_at: u64,
39    /// Whether the edge is marked as deleted
40    pub deleted: bool,
41    /// Replica that last modified the edge
42    pub last_modified_by: ReplicaId,
43}
44
45impl EdgeMetadata {
46    /// Create new metadata
47    pub fn new(replica: ReplicaId, timestamp: u64) -> Self {
48        Self {
49            created_at: timestamp,
50            modified_at: timestamp,
51            deleted: false,
52            last_modified_by: replica,
53        }
54    }
55
56    /// Mark as modified
57    pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
58        self.modified_at = timestamp;
59        self.last_modified_by = replica;
60    }
61
62    /// Mark as deleted
63    pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
64        self.deleted = true;
65        self.mark_modified(replica, timestamp);
66    }
67}
68
69/// A graph edge connecting two vertices
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
71pub struct Edge {
72    /// Unique identifier
73    pub id: EdgeId,
74    /// Source vertex ID
75    pub source: VertexId,
76    /// Target vertex ID
77    pub target: VertexId,
78    /// Optional edge weight
79    pub weight: Option<f64>,
80    /// Metadata
81    pub metadata: EdgeMetadata,
82}
83
84impl Edge {
85    /// Create a new edge
86    pub fn new(source: VertexId, target: VertexId, replica: ReplicaId, timestamp: u64) -> Self {
87        Self {
88            id: EdgeId::new(replica),
89            source,
90            target,
91            weight: None,
92            metadata: EdgeMetadata::new(replica, timestamp),
93        }
94    }
95
96    /// Create a new edge with weight
97    pub fn with_weight(source: VertexId, target: VertexId, weight: f64, replica: ReplicaId, timestamp: u64) -> Self {
98        Self {
99            id: EdgeId::new(replica),
100            source,
101            target,
102            weight: Some(weight),
103            metadata: EdgeMetadata::new(replica, timestamp),
104        }
105    }
106
107    /// Mark as modified
108    pub fn mark_modified(&mut self, replica: ReplicaId, timestamp: u64) {
109        self.metadata.mark_modified(replica, timestamp);
110    }
111
112    /// Mark as deleted
113    pub fn mark_deleted(&mut self, replica: ReplicaId, timestamp: u64) {
114        self.metadata.mark_deleted(replica, timestamp);
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121    use super::super::super::ReplicaId;
122    use uuid::Uuid;
123
124    fn create_replica(id: u64) -> ReplicaId {
125        ReplicaId::from(Uuid::from_u64_pair(0, id))
126    }
127
128    #[test]
129    fn test_edge_id_creation() {
130        let replica = create_replica(1);
131        let edge_id = EdgeId::new(replica);
132        
133        assert_eq!(edge_id.replica, replica);
134        assert_ne!(edge_id.id, Uuid::nil());
135    }
136
137    #[test]
138    fn test_edge_creation() {
139        let replica = create_replica(1);
140        let timestamp = 1234567890;
141        let source = VertexId::new(replica);
142        let target = VertexId::new(replica);
143        let edge = Edge::new(source.clone(), target.clone(), replica, timestamp);
144        
145        assert_eq!(edge.source, source);
146        assert_eq!(edge.target, target);
147        assert_eq!(edge.weight, None);
148        assert_eq!(edge.metadata.created_at, timestamp);
149        assert_eq!(edge.metadata.deleted, false);
150    }
151
152    #[test]
153    fn test_edge_with_weight() {
154        let replica = create_replica(1);
155        let timestamp = 1234567890;
156        let source = VertexId::new(replica);
157        let target = VertexId::new(replica);
158        let weight = 5.5;
159        let edge = Edge::with_weight(source.clone(), target.clone(), weight, replica, timestamp);
160        
161        assert_eq!(edge.weight, Some(weight));
162    }
163
164    #[test]
165    fn test_edge_metadata_operations() {
166        let replica = create_replica(1);
167        let timestamp = 1234567890;
168        let mut metadata = EdgeMetadata::new(replica, timestamp);
169        
170        // Test modification
171        let new_timestamp = 1234567891;
172        metadata.mark_modified(replica, new_timestamp);
173        assert_eq!(metadata.modified_at, new_timestamp);
174        
175        // Test deletion
176        let delete_timestamp = 1234567892;
177        metadata.mark_deleted(replica, delete_timestamp);
178        assert_eq!(metadata.deleted, true);
179        assert_eq!(metadata.modified_at, delete_timestamp);
180    }
181}
182