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}