graph_api_lib/graph.rs
1use crate::element::Element;
2use crate::walker::builder::{ImmutableMarker, MutableMarker, StartWalkerBuilder};
3use crate::{EdgeSearch, Value, walker};
4use crate::{Label, VertexSearch};
5use derivative::Derivative;
6use std::fmt::Debug;
7use std::hash::Hash;
8
9/// The direction of an edge in a graph.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord)]
11#[repr(u8)]
12pub enum Direction {
13 /// Outgoing edges.
14 Outgoing,
15
16 /// Incoming edges.
17 Incoming,
18
19 /// Both incoming and outgoing edges.
20 #[default]
21 All,
22}
23
24impl Direction {
25 /// Returns the reverse of this direction.
26 ///
27 /// - `Outgoing` becomes `Incoming`
28 /// - `Incoming` becomes `Outgoing`
29 /// - `All` remains `All`
30 ///
31 /// # Returns
32 /// The reversed direction.
33 pub fn reverse(&self) -> Self {
34 match self {
35 Direction::Outgoing => Direction::Incoming,
36 Direction::Incoming => Direction::Outgoing,
37 Direction::All => Direction::All,
38 }
39 }
40}
41
42/// An identifier for a vertex or an edge in a graph.
43#[derive(Debug, Derivative)]
44#[derivative(
45 Copy(bound = ""),
46 Clone(bound = ""),
47 Eq(bound = ""),
48 PartialEq(bound = ""),
49 Hash(bound = "")
50)]
51pub enum ElementId<Graph>
52where
53 Graph: crate::Graph,
54{
55 /// A vertex identifier.
56 Vertex(Graph::VertexId),
57
58 /// An edge identifier.
59 Edge(Graph::EdgeId),
60}
61
62/// Graphs that implement this trait can be used with the walker API.
63pub trait Graph: Sized + Debug {
64 /// The type of the vertices in the graph. This is usually an enum.
65 type Vertex: Debug + Element;
66
67 /// The type of the edges in the graph. This is usually an enum.
68 type Edge: Debug + Element;
69
70 /// The `VertexId` type of the graph.
71 type VertexId: Debug + Eq + PartialEq + Copy + Clone + Hash + Into<ElementId<Self>> + 'static;
72
73 /// The `EdgeId` type of the graph.
74 type EdgeId: Debug + Eq + PartialEq + Copy + Clone + Hash + Into<ElementId<Self>> + 'static;
75
76 /// A reference to a vertex.
77 type VertexReference<'graph>: VertexReference<'graph, Self>
78 where
79 Self: 'graph;
80
81 /// A mut reference to a vertex.
82 type VertexReferenceMut<'graph>: VertexReferenceMut<'graph, Self>
83 where
84 Self: 'graph;
85
86 /// An edge reference is used during walking over edges. It includes the id, tail, head and weight of the edge.
87 type EdgeReference<'graph>: EdgeReference<'graph, Self>
88 where
89 Self: 'graph;
90
91 /// A mut edge reference to modify the edge.
92 type EdgeReferenceMut<'graph>: EdgeReferenceMut<'graph, Self>
93 where
94 Self: 'graph;
95
96 /// An iterator over the edge references.
97 type EdgeIter<'search, 'graph>: Iterator<Item = Self::EdgeReference<'graph>>
98 where
99 Self: 'graph;
100
101 /// An iterator over the vertex references.
102 type VertexIter<'search, 'graph>: Iterator<Item = Self::VertexReference<'graph>>
103 where
104 Self: 'graph;
105
106 /// Adds a vertex to the graph and returns its identifier.
107 fn add_vertex(&mut self, vertex: Self::Vertex) -> Self::VertexId;
108
109 /// Adds an edge to the graph and returns its identifier.
110 fn add_edge(
111 &mut self,
112 from: Self::VertexId,
113 to: Self::VertexId,
114 edge: Self::Edge,
115 ) -> Self::EdgeId;
116
117 /// Gets the vertex with the specified identifier.
118 fn vertex(&self, id: Self::VertexId) -> Option<Self::VertexReference<'_>>;
119
120 /// Returns the vertex with the specified identifier.
121 fn vertex_mut(&mut self, id: Self::VertexId) -> Option<Self::VertexReferenceMut<'_>>;
122
123 /// Iterate over vertex identifiers.
124 /// Graphs should try to narrow down the returned vertices using the search criteria, but overfetch will be filtered.
125 fn vertices<'search>(
126 &self,
127 vertex_search: &VertexSearch<'search, Self>,
128 ) -> Self::VertexIter<'search, '_>;
129
130 /// Gets the edge with the specified identifier.
131 fn edge(&self, id: Self::EdgeId) -> Option<Self::EdgeReference<'_>>;
132
133 /// Gets the edge with the specified identifier.
134 fn edge_mut(&mut self, id: Self::EdgeId) -> Option<Self::EdgeReferenceMut<'_>>;
135
136 /// Returns an iterator over the edges of a vertex.
137 /// Graphs should try to narrow down the returned edges using the search criteria, but overfetch will be filtered.
138 fn edges<'search>(
139 &self,
140 id: Self::VertexId,
141 search: &EdgeSearch<'search, Self>,
142 ) -> Self::EdgeIter<'search, '_>;
143
144 /// Clears the graph. Default implementation returns an error.
145 /// Implement the `SupportsClear` trait to provide this functionality.
146 fn clear(&mut self) {
147 panic!("This graph implementation does not support clearing")
148 }
149
150 /// Returns a string representation of an element in the graph.
151 fn dbg<T: Into<ElementId<Self>>>(&self, id: T) -> String {
152 match id.into() {
153 ElementId::Vertex(vertex_id) => self
154 .vertex(vertex_id)
155 .map_or_else(|| "<missing>".to_string(), |vertex| format!("{:?}", vertex)),
156 ElementId::Edge(edge_id) => self
157 .edge(edge_id)
158 .map_or_else(|| "<missing>".to_string(), |edge| format!("{:?}", edge)),
159 }
160 }
161
162 /// Returns an immutable walker builder for the graph.
163 fn walk(&self) -> StartWalkerBuilder<ImmutableMarker, Self, ()>
164 where
165 Self: Sized,
166 {
167 walker::builder::new_start(self)
168 }
169
170 /// Returns a mutable walker builder for the graph.
171 fn walk_mut(&mut self) -> StartWalkerBuilder<MutableMarker, Self, ()>
172 where
173 Self: Sized,
174 {
175 walker::builder::new_start_mut(self)
176 }
177}
178
179pub trait VertexReference<'graph, Graph>: Debug
180where
181 Graph: crate::Graph,
182{
183 /// Return the ID of the vertex
184 fn id(&self) -> Graph::VertexId;
185
186 /// Return the weight of the vertex
187 fn weight(&self) -> &Graph::Vertex;
188
189 /// Project the element to a mutation safe struct representing a single labelled vertex.
190 fn project<'reference, T: Project<'reference, <Graph as crate::Graph>::Vertex>>(
191 &'reference self,
192 ) -> Option<T>;
193}
194
195pub trait VertexReferenceMut<'graph, Graph>: VertexReference<'graph, Graph>
196where
197 Graph: crate::graph::Graph + 'graph,
198{
199 type MutationListener<'reference>: MutationListener<'reference, Graph::Vertex>;
200 /// Get the raw mutable vertex weight.
201 /// WARNING! It is advised to use the generated projections to get a typed reference to the vertex and use the set_ methods instead.
202 /// It is only safe to use this if you are mutating non-indexed fields.
203 /// Incorrect usage of this method will result in graph indexes being corrupted.
204 fn weight_mut(&mut self) -> &mut Graph::Vertex;
205
206 /// Project the element to a mutation safe struct representing a single labelled vertex. Modifications to the projection will be reflected in graph indexes.
207 fn project_mut<
208 'reference,
209 T: ProjectMut<'reference, <Graph as crate::Graph>::Vertex, Self::MutationListener<'reference>>,
210 >(
211 &'reference mut self,
212 ) -> Option<T>;
213}
214
215/// A reference to an edge in a graph.
216pub trait EdgeReference<'graph, Graph>: Debug
217where
218 Graph: crate::graph::Graph,
219{
220 /// Returns the identifier of the edge.
221 fn id(&self) -> Graph::EdgeId;
222
223 /// Returns the identifier of the tail vertex of the edge.
224 fn tail(&self) -> Graph::VertexId;
225
226 /// Returns the identifier of the head vertex of the edge.
227 fn head(&self) -> Graph::VertexId;
228
229 /// Returns a reference to the weight of the edge.
230 fn weight(&self) -> &Graph::Edge;
231
232 /// Project the element to a struct representing a single labelled edge.
233 fn project<'reference, T: Project<'reference, <Graph as crate::Graph>::Edge>>(
234 &'reference self,
235 ) -> Option<T>;
236}
237
238/// A mutable reference to an edge in a graph.
239/// This trait extends the `EdgeReference` trait and provides a method to
240/// obtain a mutable reference to the weight of the edge.
241pub trait EdgeReferenceMut<'graph, Graph>: EdgeReference<'graph, Graph>
242where
243 Graph: crate::Graph,
244{
245 type MutationListener<'reference>: MutationListener<'reference, Graph::Edge>;
246
247 /// Get the raw mutable vertex weight.
248 /// WARNING! It is advised to use the generated projections to get a typed reference to the vertex and use the set_ methods instead.
249 /// It is only safe to use this if you are mutating non-indexed fields.
250 /// Incorrect usage of this method will result in graph indexes being corrupted.
251 fn weight_mut(&mut self) -> &mut Graph::Edge;
252
253 /// Project the element to a mutation safe struct representing a single labelled edge. Modifications to the projection will be reflected in graph indexes.
254 fn project_mut<
255 'reference,
256 T: ProjectMut<'reference, <Graph as crate::Graph>::Edge, Self::MutationListener<'reference>>,
257 >(
258 &'reference mut self,
259 ) -> Option<T>;
260}
261
262/// Enables projecting a graph element weight to a specific type.
263///
264/// This trait provides a mechanism to safely convert a generic graph element
265/// (vertex or edge) to a specific, strongly-typed representation.
266///
267/// # Type Parameters
268/// - `'reference`: The lifetime of the reference to the weight
269/// - `Weight`: The type of the element weight being projected
270pub trait Project<'reference, Weight>
271where
272 Weight: Element,
273 Self: Sized,
274{
275 /// Attempts to convert a weight to this specific type.
276 ///
277 /// # Parameters
278 /// - `weight`: The element weight to project
279 ///
280 /// # Returns
281 /// `Some(Self)` if the weight can be projected to this type, `None` otherwise.
282 fn project(weight: &'reference Weight) -> Option<Self>;
283}
284
285/// Enables projecting a graph element weight to a mutable specific type.
286///
287/// This trait provides a mechanism to safely convert a generic graph element
288/// (vertex or edge) to a specific, strongly-typed mutable representation.
289/// Changes to the projected type will be tracked using the mutation listener.
290///
291/// # Type Parameters
292/// - `'reference`: The lifetime of the mutable reference to the weight
293/// - `Weight`: The type of the element weight being projected
294/// - `MutationListener`: A type that listens for mutations to track index updates
295pub trait ProjectMut<'reference, Weight, MutationListener>
296where
297 Weight: Element,
298 MutationListener: crate::MutationListener<'reference, Weight>,
299 Self: Sized,
300{
301 /// Attempts to convert a weight to this specific mutable type.
302 ///
303 /// # Parameters
304 /// - `weight`: The element weight to project
305 /// - `mutation_listener`: The listener that will track mutations to the weight
306 ///
307 /// # Returns
308 /// `Some(Self)` if the weight can be projected to this type, `None` otherwise.
309 fn project_mut(
310 weight: &'reference mut Weight,
311 mutation_listener: MutationListener,
312 ) -> Option<Self>;
313}
314
315/// Trait to allow graphs to react to mutation of elements.
316/// When an indexed element is updated the mutation listener is called with the index and the before and after values.
317pub trait MutationListener<'reference, Element>
318where
319 Element: crate::Element,
320{
321 /// Called when a setter is called on a projection of an indexed `Element`.
322 fn update(&mut self, index: <Element::Label as Label>::Index, before: Value, after: Value);
323}
324
325impl<Element> MutationListener<'_, Element> for ()
326where
327 Element: crate::Element,
328{
329 fn update(&mut self, _index: <Element::Label as Label>::Index, _before: Value, _after: Value) {}
330}