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}