Add an edge to the graph
(&mut self, edge: Edge)
| 77 | |
| 78 | /// Add an edge to the graph |
| 79 | pub fn add_edge(&mut self, edge: Edge) -> Result<(), GraphError> { |
| 80 | // Check if edge already exists |
| 81 | if self.edges.contains_key(&edge.id) { |
| 82 | return Err(GraphError::EdgeAlreadyExists(edge.id)); |
| 83 | } |
| 84 | |
| 85 | // Check for semantic duplicate edge (same source, target, label, and properties) |
| 86 | let has_duplicate = self.edges.values().any(|existing_edge| { |
| 87 | existing_edge.from_node == edge.from_node |
| 88 | && existing_edge.to_node == edge.to_node |
| 89 | && existing_edge.label == edge.label |
| 90 | && existing_edge.properties == edge.properties |
| 91 | }); |
| 92 | |
| 93 | if has_duplicate { |
| 94 | return Err(GraphError::EdgeAlreadyExists(format!( |
| 95 | "Relationship already exists: ({}) -[{}]-> ({})", |
| 96 | edge.from_node, edge.label, edge.to_node |
| 97 | ))); |
| 98 | } |
| 99 | |
| 100 | // Verify that both nodes exist |
| 101 | if !self.nodes.contains_key(&edge.from_node) { |
| 102 | return Err(GraphError::InvalidEdge { |
| 103 | from: edge.from_node.clone(), |
| 104 | to: edge.to_node.clone(), |
| 105 | }); |
| 106 | } |
| 107 | if !self.nodes.contains_key(&edge.to_node) { |
| 108 | return Err(GraphError::InvalidEdge { |
| 109 | from: edge.from_node.clone(), |
| 110 | to: edge.to_node.clone(), |
| 111 | }); |
| 112 | } |
| 113 | |
| 114 | // Update edge label index |
| 115 | self.edge_labels |
| 116 | .entry(edge.label.clone()) |
| 117 | .or_default() |
| 118 | .push(edge.id.clone()); |
| 119 | |
| 120 | // Update adjacency lists |
| 121 | self.adjacency_out |
| 122 | .get_mut(&edge.from_node) |
| 123 | .unwrap() |
| 124 | .push(edge.id.clone()); |
| 125 | |
| 126 | self.adjacency_in |
| 127 | .get_mut(&edge.to_node) |
| 128 | .unwrap() |
| 129 | .push(edge.id.clone()); |
| 130 | |
| 131 | // Store the edge |
| 132 | self.edges.insert(edge.id.clone(), edge); |
| 133 | |
| 134 | Ok(()) |
| 135 | } |
| 136 |
no test coverage detected