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 /// Removes a vertex from the graph and returns the vertex.
118 fn remove_vertex(&mut self, id: Self::VertexId) -> Option<Self::Vertex>;
119
120 /// Removes an edge from the graph and returns the edge.
121 fn remove_edge(&mut self, id: Self::EdgeId) -> Option<Self::Edge>;
122
123 /// Gets the vertex with the specified identifier.
124 fn vertex(&self, id: Self::VertexId) -> Option<Self::VertexReference<'_>>;
125
126 /// Returns the vertex with the specified identifier.
127 fn vertex_mut(&mut self, id: Self::VertexId) -> Option<Self::VertexReferenceMut<'_>>;
128
129 /// Iterate over vertex identifiers.
130 /// Graphs should try to narrow down the returned vertices using the search criteria, but overfetch will be filtered.
131 fn vertices<'search>(
132 &self,
133 vertex_search: &VertexSearch<'search, Self>,
134 ) -> Self::VertexIter<'search, '_>;
135
136 /// Gets the edge with the specified identifier.
137 fn edge(&self, id: Self::EdgeId) -> Option<Self::EdgeReference<'_>>;
138
139 /// Gets the edge with the specified identifier.
140 fn edge_mut(&mut self, id: Self::EdgeId) -> Option<Self::EdgeReferenceMut<'_>>;
141
142 /// Returns an iterator over the edges of a vertex.
143 /// Graphs should try to narrow down the returned edges using the search criteria, but overfetch will be filtered.
144 fn edges<'search>(
145 &self,
146 id: Self::VertexId,
147 search: &EdgeSearch<'search, Self>,
148 ) -> Self::EdgeIter<'search, '_>;
149
150 /// Clears the graph. Default implementation returns an error.
151 /// Implement the `SupportsClear` trait to provide this functionality.
152 fn clear(&mut self) {
153 panic!("This graph implementation does not support clearing")
154 }
155
156 /// Returns a string representation of an element in the graph.
157 fn dbg<T: Into<ElementId<Self>>>(&self, id: T) -> String {
158 match id.into() {
159 ElementId::Vertex(vertex_id) => self
160 .vertex(vertex_id)
161 .map_or_else(|| "<missing>".to_string(), |vertex| format!("{:?}", vertex)),
162 ElementId::Edge(edge_id) => self
163 .edge(edge_id)
164 .map_or_else(|| "<missing>".to_string(), |edge| format!("{:?}", edge)),
165 }
166 }
167
168 /// Returns an immutable walker builder for the graph.
169 fn walk(&self) -> StartWalkerBuilder<ImmutableMarker, Self, ()>
170 where
171 Self: Sized,
172 {
173 walker::builder::new_start(self)
174 }
175
176 /// Returns a mutable walker builder for the graph.
177 fn walk_mut(&mut self) -> StartWalkerBuilder<MutableMarker, Self, ()>
178 where
179 Self: Sized,
180 {
181 walker::builder::new_start_mut(self)
182 }
183}
184
185pub trait VertexReference<'graph, Graph>: Debug
186where
187 Graph: crate::Graph,
188{
189 /// Return the ID of the vertex
190 fn id(&self) -> Graph::VertexId;
191
192 /// Return the weight of the vertex
193 fn weight(&self) -> &Graph::Vertex;
194
195 /// Project the element to a mutation safe struct representing a single labelled vertex.
196 fn project<'reference, T: Project<'reference, <Graph as crate::Graph>::Vertex>>(
197 &'reference self,
198 ) -> Option<T>;
199}
200
201pub trait VertexReferenceMut<'graph, Graph>: VertexReference<'graph, Graph>
202where
203 Graph: crate::graph::Graph + 'graph,
204{
205 type MutationListener<'reference>: MutationListener<'reference, Graph::Vertex>;
206 /// Get the raw mutable vertex weight.
207 /// WARNING! It is advised to use the generated projections to get a typed reference to the vertex and use the set_ methods instead.
208 /// It is only safe to use this if you are mutating non-indexed fields.
209 /// Incorrect usage of this method will result in graph indexes being corrupted.
210 fn weight_mut(&mut self) -> &mut Graph::Vertex;
211
212 /// Project the element to a mutation safe struct representing a single labelled vertex. Modifications to the projection will be reflected in graph indexes.
213 fn project_mut<
214 'reference,
215 T: ProjectMut<'reference, <Graph as crate::Graph>::Vertex, Self::MutationListener<'reference>>,
216 >(
217 &'reference mut self,
218 ) -> Option<T>;
219}
220
221/// A reference to an edge in a graph.
222pub trait EdgeReference<'graph, Graph>: Debug
223where
224 Graph: crate::graph::Graph,
225{
226 /// Returns the identifier of the edge.
227 fn id(&self) -> Graph::EdgeId;
228
229 /// Returns the identifier of the tail vertex of the edge.
230 fn tail(&self) -> Graph::VertexId;
231
232 /// Returns the identifier of the head vertex of the edge.
233 fn head(&self) -> Graph::VertexId;
234
235 /// Returns a reference to the weight of the edge.
236 fn weight(&self) -> &Graph::Edge;
237
238 /// Project the element to a struct representing a single labelled edge.
239 fn project<'reference, T: Project<'reference, <Graph as crate::Graph>::Edge>>(
240 &'reference self,
241 ) -> Option<T>;
242}
243
244/// A mutable reference to an edge in a graph.
245/// This trait extends the `EdgeReference` trait and provides a method to
246/// obtain a mutable reference to the weight of the edge.
247pub trait EdgeReferenceMut<'graph, Graph>: EdgeReference<'graph, Graph>
248where
249 Graph: crate::Graph,
250{
251 type MutationListener<'reference>: MutationListener<'reference, Graph::Edge>;
252
253 /// Get the raw mutable vertex weight.
254 /// WARNING! It is advised to use the generated projections to get a typed reference to the vertex and use the set_ methods instead.
255 /// It is only safe to use this if you are mutating non-indexed fields.
256 /// Incorrect usage of this method will result in graph indexes being corrupted.
257 fn weight_mut(&mut self) -> &mut Graph::Edge;
258
259 /// Project the element to a mutation safe struct representing a single labelled edge. Modifications to the projection will be reflected in graph indexes.
260 fn project_mut<
261 'reference,
262 T: ProjectMut<'reference, <Graph as crate::Graph>::Edge, Self::MutationListener<'reference>>,
263 >(
264 &'reference mut self,
265 ) -> Option<T>;
266}
267
268/// Enables projecting a graph element weight to a specific type.
269///
270/// This trait provides a mechanism to safely convert a generic graph element
271/// (vertex or edge) to a specific, strongly-typed representation.
272///
273/// # Type Parameters
274/// - `'reference`: The lifetime of the reference to the weight
275/// - `Weight`: The type of the element weight being projected
276pub trait Project<'reference, Weight>
277where
278 Weight: Element,
279 Self: Sized,
280{
281 /// Attempts to convert a weight to this specific type.
282 ///
283 /// # Parameters
284 /// - `weight`: The element weight to project
285 ///
286 /// # Returns
287 /// `Some(Self)` if the weight can be projected to this type, `None` otherwise.
288 fn project(weight: &'reference Weight) -> Option<Self>;
289}
290
291/// Enables projecting a graph element weight to a mutable specific type.
292///
293/// This trait provides a mechanism to safely convert a generic graph element
294/// (vertex or edge) to a specific, strongly-typed mutable representation.
295/// Changes to the projected type will be tracked using the mutation listener.
296///
297/// # Type Parameters
298/// - `'reference`: The lifetime of the mutable reference to the weight
299/// - `Weight`: The type of the element weight being projected
300/// - `MutationListener`: A type that listens for mutations to track index updates
301pub trait ProjectMut<'reference, Weight, MutationListener>
302where
303 Weight: Element,
304 MutationListener: crate::MutationListener<'reference, Weight>,
305 Self: Sized,
306{
307 /// Attempts to convert a weight to this specific mutable type.
308 ///
309 /// # Parameters
310 /// - `weight`: The element weight to project
311 /// - `mutation_listener`: The listener that will track mutations to the weight
312 ///
313 /// # Returns
314 /// `Some(Self)` if the weight can be projected to this type, `None` otherwise.
315 fn project_mut(
316 weight: &'reference mut Weight,
317 mutation_listener: MutationListener,
318 ) -> Option<Self>;
319}
320
321/// Trait to allow graphs to react to mutation of elements.
322/// When an indexed element is updated the mutation listener is called with the index and the before and after values.
323pub trait MutationListener<'reference, Element>
324where
325 Element: crate::Element,
326{
327 /// Called when a setter is called on a projection of an indexed `Element`.
328 fn update(&mut self, index: <Element::Label as Label>::Index, before: Value, after: Value);
329}
330
331impl<Element> MutationListener<'_, Element> for ()
332where
333 Element: crate::Element,
334{
335 fn update(&mut self, _index: <Element::Label as Label>::Index, _before: Value, _after: Value) {}
336}