cairn_knowledge_graph/graph/edge/edge.rs
1use crate::error::{GraphComputingError, LogicError, LogicErrorType};
2use crate::graph::graph::Graph;
3use crate::graph::vertex::{VertexIndex, VertexKey};
4
5use super::adjacency_matrix::EdgeCoordinate;
6use super::edge_type::{EdgeType, EdgeTypeIndex, EdgeTypeRef};
7
8// pub enum Edge {
9// Directed(DirectedEdge),
10// }
11
12// TODO: add constructor with indices
13// TODO: consider modelling a DirectedEdge as an enum. Each variant can model a different state/representation. E.g. defintion by keys, by indices, with existing vertices, with new vertices, etc.
14
15// enum DirectedEdge {
16// DefinedByIndicesAndKeys(DirectedEdgeDefinedByIndicesAndKeys),
17// DefinedByIndices(DirectedEdgeDefinedByIndices),
18// DefinedByKeys(DirectedEdgeDefinedByKeys)
19// }
20
21// Design note: The Vertex and Edge structs do not contain a reference to the Graph.
22// Such a reference would be an immutable reference to the graph.
23// Then, the graph cannot be modified as long as this edge/vertex exists.
24
25pub(crate) trait EdgeToEdgeCoordinate {
26 fn key_defined_edge_to_edge_coordinate(
27 &self,
28 edge: &DirectedEdgeDefinedByKeys,
29 ) -> Result<EdgeCoordinate, GraphComputingError>;
30 fn index_defined_edge_to_edge_coordinate(
31 &self,
32 edge: &DirectedEdgeDefinedByIndices,
33 ) -> Result<EdgeCoordinate, GraphComputingError>;
34}
35
36impl EdgeToEdgeCoordinate for Graph {
37 fn key_defined_edge_to_edge_coordinate(
38 &self,
39 edge: &DirectedEdgeDefinedByKeys,
40 ) -> Result<EdgeCoordinate, GraphComputingError> {
41 // let mut from_vertex_index = self
42 // .vertex_key_to_vertex_index_map
43 // .get(edge.originates_from_vertex());
44 let from_vertex_index;
45 match self
46 .vertex_key_to_vertex_index_map_ref()
47 .get(edge.originates_from_vertex())
48 {
49 Some(index) => from_vertex_index = index,
50 None => {
51 return Err(LogicError::new(
52 LogicErrorType::VertexMustExist,
53 format!(
54 "No vertex found for from-vertex with key: {}",
55 edge.originates_from_vertex()
56 ),
57 None,
58 )
59 .into())
60 }
61 }
62 // let to_vertex_index = self
63 // .vertex_key_to_vertex_index_map
64 // .get(edge.goes_to_vertex())
65 // .unwrap();
66 let to_vertex_index;
67 match self
68 .vertex_key_to_vertex_index_map_ref()
69 .get(edge.points_to_vertex())
70 {
71 Some(index) => to_vertex_index = index,
72 None => {
73 return Err(LogicError::new(
74 LogicErrorType::VertexMustExist,
75 format!(
76 "No vertex found for to-vertex with key: {}",
77 edge.points_to_vertex()
78 ),
79 None,
80 )
81 .into())
82 }
83 }
84
85 Ok(EdgeCoordinate::new(
86 *from_vertex_index.index_ref(),
87 *to_vertex_index.index_ref(),
88 ))
89 }
90
91 fn index_defined_edge_to_edge_coordinate(
92 &self,
93 edge: &DirectedEdgeDefinedByIndices,
94 ) -> Result<EdgeCoordinate, GraphComputingError> {
95 Ok(EdgeCoordinate::new(
96 edge.originates_from_vertex().index(),
97 edge.points_to_vertex().index(),
98 ))
99 }
100}
101
102#[derive(Clone, Debug, PartialEq)]
103pub struct DirectedEdgeDefinedByKeys {
104 from_vertex: VertexKey,
105 edge_type: EdgeType,
106 to_vertex: VertexKey,
107}
108
109#[derive(Clone, Copy, Debug, PartialEq)]
110pub struct DirectedEdgeDefinedByIndices {
111 from_vertex: VertexIndex,
112 edge_type: EdgeTypeIndex,
113 to_vertex: VertexIndex,
114}
115
116impl DirectedEdgeDefinedByKeys {
117 pub fn new(from_vertex: VertexKey, edge_type: EdgeType, to_vertex: VertexKey) -> Self {
118 // TODO: review if a self-connected edge is allowed
119 Self {
120 from_vertex,
121 edge_type,
122 to_vertex,
123 }
124 }
125
126 pub fn edge_type_ref(&self) -> &EdgeTypeRef {
127 &self.edge_type.as_str()
128 }
129 pub fn originates_from_vertex(&self) -> &VertexKey {
130 &self.from_vertex
131 }
132 pub fn points_to_vertex(&self) -> &VertexKey {
133 &self.to_vertex
134 }
135}
136
137impl DirectedEdgeDefinedByIndices {
138 pub fn new(from_vertex: VertexIndex, edge_type: EdgeTypeIndex, to_vertex: VertexIndex) -> Self {
139 // TODO: review if a self-connected edge is allowed
140 Self {
141 from_vertex,
142 edge_type,
143 to_vertex,
144 }
145 }
146
147 pub fn edge_type(&self) -> &EdgeTypeIndex {
148 &self.edge_type
149 }
150 pub fn originates_from_vertex(&self) -> &VertexIndex {
151 &self.from_vertex
152 }
153 pub fn points_to_vertex(&self) -> &VertexIndex {
154 &self.to_vertex
155 }
156}
157
158// TODO: is this struct useful? What would be it's use-case?
159// pub struct DirectedEdgeSpecificationUsingIndicesAndKeys {
160// edge_type_index: EdgeTypeIndex,
161// from_vertex_index: VertexIndex,
162// to_vertex_index: VertexIndex,
163
164// edge_type: EdgeType,
165// from_vertex_key: VertexKey,
166// to_vertex_key: VertexKey,
167// }
168
169// impl DirectedEdgeTrait for DirectedEdgeDefinedByIndices {
170// fn edge_type_ref(&self) -> &EdgeTypeRef {
171
172// }
173// fn edge_type_index(&self) -> &EdgeTypeIndex {
174// &self.edge_type
175// }
176
177// fn originates_from_vertex_with_key(&self) -> &VertexKey;
178// fn originates_from_vertex_with_index(&self) -> &VertexIndex {
179// &self.from_vertex
180// }
181
182// fn points_to_vertex_with_key(&self) -> &VertexKey;
183// fn points_to_vertex_with_index(&self) -> &VertexIndex {
184// &self.to_vertex
185// }
186// }
187
188// impl DirectedEdgeTrait for DirectedEdgeDefinedByKeys {
189// fn edge_type_ref(&self) -> &EdgeTypeRef;
190// fn edge_type_index(&self) -> &EdgeTypeIndex;
191
192// fn originates_from_vertex(&self) -> &Vertex;
193// fn originates_from_vertex_with_key(&self) -> &VertexKey;
194// fn originates_from_vertex_with_index(&self) -> &VertexIndex;
195
196// fn points_to_vertex(&self) -> &Vertex;
197// fn points_to_vertex_with_key(&self) -> &VertexKey;
198// fn points_to_vertex_with_index(&self) -> &VertexIndex;
199// }
200
201// // REVIEW: should an edge have a value, or even properties?
202// // TODO: use const generics
203// #[derive(Debug, Clone)]
204// pub struct DirectedEdge {
205// // key: EdgeKey,
206// edge_type: EdgeType,
207// from_vertex: VertexKey,
208// to_vertex: VertexKey,
209// }