Skip to main content

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// }