cairn_knowledge_graph/operations/
add_edge.rs1use crate::error::{GraphComputingError, LogicError, LogicErrorType, SystemError, SystemErrorType};
2
3use crate::graph::edge::adjacency_matrix::EdgeCoordinate;
4use crate::graph::edge::{
5 DirectedEdgeDefinedByIndices, DirectedEdgeDefinedByKeys, EdgeToEdgeCoordinate, EdgeTypeIndex,
6};
7use crate::graph::graph::Graph;
8
9use super::add_edge_type::AddEdgeType;
10
11pub trait AddEdge {
12 fn add_edge_using_keys(
13 &mut self,
14 edge: DirectedEdgeDefinedByKeys,
15 ) -> Result<(), GraphComputingError>;
16
17 fn add_edge_and_edge_type_using_keys(
20 &mut self,
21 edge: DirectedEdgeDefinedByKeys,
22 ) -> Result<EdgeTypeIndex, GraphComputingError>;
23
24 fn add_edge_using_indices(
25 &mut self,
26 edge: DirectedEdgeDefinedByIndices,
27 ) -> Result<(), GraphComputingError>;
28}
29
30impl AddEdge for Graph {
31 fn add_edge_using_keys(
32 &mut self,
33 edge: DirectedEdgeDefinedByKeys,
34 ) -> Result<(), GraphComputingError> {
35 let edge_type_index: EdgeTypeIndex;
36 match self
37 .edge_type_to_edge_type_index_map_ref()
38 .get(edge.edge_type_ref())
39 {
40 None => {
41 return Err(LogicError::new(
42 LogicErrorType::EdgeTypeMustExist,
43 format!("EdgeType \"{}\" does not exist", edge.edge_type_ref()),
44 None,
45 )
46 .into())
47 }
48 Some(index) => {
49 edge_type_index = index.clone(); }
51 }
52 let edge_coordinate = self.key_defined_edge_to_edge_coordinate(&edge)?;
53 self.set_edge_in_adjacency_matrix(&edge_coordinate, edge_type_index.clone())?; Ok(())
55 }
56
57 fn add_edge_and_edge_type_using_keys(
60 &mut self,
61 edge: DirectedEdgeDefinedByKeys,
62 ) -> Result<EdgeTypeIndex, GraphComputingError> {
63 let edge_type_index: EdgeTypeIndex;
64 match self
65 .edge_type_to_edge_type_index_map_ref()
66 .get(edge.edge_type_ref())
67 {
68 None => {
69 edge_type_index = self.add_new_edge_type(edge.edge_type_ref().to_owned())?;
70 }
71 Some(index) => {
72 edge_type_index = index.clone(); }
74 }
75 let edge_coordinate = self.key_defined_edge_to_edge_coordinate(&edge)?;
76 self.set_edge_in_adjacency_matrix(&edge_coordinate, edge_type_index.clone())?;
77 Ok(edge_type_index)
78 }
79
80 fn add_edge_using_indices(
81 &mut self,
82 edge: DirectedEdgeDefinedByIndices,
83 ) -> Result<(), GraphComputingError> {
84 let edge_coordinate = self.index_defined_edge_to_edge_coordinate(&edge)?;
85 self.set_edge_in_adjacency_matrix(&edge_coordinate, edge.edge_type().clone())?;
86 Ok(())
87 }
88}
89
90impl Graph {
91 fn set_edge_in_adjacency_matrix(
92 &mut self,
93 edge_coordinate: &EdgeCoordinate,
94 edge_type_index: EdgeTypeIndex,
95 ) -> Result<(), GraphComputingError> {
96 match self
97 .adjacency_matrices_mut_ref()
98 .get_mut_ref(edge_type_index)
99 {
100 Ok(edge_type_adjacency_matrix) => {
101 edge_type_adjacency_matrix.add_edge(&edge_coordinate)?
102 }
103 Err(_) => {
104 return Err(SystemError::new(
106 SystemErrorType::IndexOutOfBounds,
107 format!(
108 "Unable to access adjacency matrix at index: {}",
109 edge_type_index.index_ref()
110 ),
111 None,
112 )
113 .into());
114 }
115 }
116 Ok(())
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 use crate::graph::graph::Graph;
125 use crate::graph::vertex::Vertex;
126 use crate::operations::add_vertex::AddVertex;
127 use crate::operations::read_edge::ReadEdge;
128
129 #[test]
130 fn add_edge() {
131 let mut graph = Graph::new(5, 5).unwrap();
132
133 let vertex_1 = Vertex::new(String::from("vertex_1"), String::from("vertex_1").into());
134 let vertex_2 = Vertex::new(String::from("vertex_2"), String::from("vertex_2").into());
135
136 let edge_vertex1_vertex2 = DirectedEdgeDefinedByKeys::new(
137 vertex_1.clone().into(),
138 String::from("edge_type_1"),
139 vertex_2.clone().into(),
140 );
141 let edge_vertex2_vertex1 = DirectedEdgeDefinedByKeys::new(
142 vertex_2.clone().into(),
143 String::from("edge_type_1"),
144 vertex_1.clone().into(),
145 );
146 let edge_vertex1_vertex2_type2 = DirectedEdgeDefinedByKeys::new(
147 vertex_1.clone().into(),
148 String::from("edge_type_2"),
149 vertex_2.clone().into(),
150 );
151
152 graph.add_or_replace_vertex(vertex_1.clone()).unwrap();
153 graph.add_or_replace_vertex(vertex_2.clone()).unwrap();
154
155 graph
156 .add_edge_and_edge_type_using_keys(edge_vertex1_vertex2.clone())
157 .unwrap();
158 assert_eq!(
159 graph
160 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2)
161 .unwrap(),
162 true
163 );
164 assert!(!graph
165 .is_key_defined_edge_in_graph(&edge_vertex2_vertex1)
166 .unwrap());
167 assert!(!graph
168 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2_type2)
169 .unwrap());
170
171 graph
172 .add_edge_and_edge_type_using_keys(edge_vertex1_vertex2.clone())
173 .unwrap();
174 graph
175 .add_edge_and_edge_type_using_keys(edge_vertex2_vertex1.clone())
176 .unwrap();
177 assert!(graph
178 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2)
179 .unwrap());
180 assert!(graph
181 .is_key_defined_edge_in_graph(&edge_vertex2_vertex1)
182 .unwrap());
183 assert!(!graph
184 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2_type2)
185 .unwrap());
186
187 graph
188 .add_edge_and_edge_type_using_keys(edge_vertex1_vertex2_type2.clone())
189 .unwrap();
190 assert!(graph
191 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2)
192 .unwrap());
193 assert!(graph
194 .is_key_defined_edge_in_graph(&edge_vertex2_vertex1)
195 .unwrap());
196 assert!(graph
197 .is_key_defined_edge_in_graph(&edge_vertex1_vertex2_type2)
198 .unwrap());
199 }
200
201 #[test]
202 fn add_edge_errors() {
203 let mut graph = Graph::new(5, 5).unwrap();
204
205 let vertex_1 = Vertex::new(String::from("vertex_1"), String::from("vertex_1").into());
206 let vertex_2 = Vertex::new(String::from("vertex_2"), String::from("vertex_2").into());
207
208 let edge_vertex1_vertex2 = DirectedEdgeDefinedByKeys::new(
209 vertex_1.clone().into(),
210 String::from("edge_type_1"),
211 vertex_2.clone().into(),
212 );
213
214 match graph.add_edge_and_edge_type_using_keys(edge_vertex1_vertex2.clone()) {
215 Err(_) => assert!(true),
216 Ok(_) => assert!(false),
217 }
218
219 graph.add_or_replace_vertex(vertex_1.clone()).unwrap();
220 match graph.add_edge_and_edge_type_using_keys(edge_vertex1_vertex2) {
221 Err(_) => assert!(true),
222 Ok(_) => assert!(false),
223 }
224 }
225}