1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use crate::ElementId;
use crate::graph::Graph;
use crate::walker::builder::{StartWalkerBuilder, VertexWalkerBuilder};
use crate::walker::steps::Empty;
use crate::walker::{VertexWalker, Walker};
use include_doc::function_body;
use std::marker::PhantomData;
// ================ VERTEX_ITER IMPLEMENTATION ================
pub struct VertexIter<'graph, Parent, Iter>
where
Parent: VertexWalker<'graph>,
Iter: Iterator<Item = <Parent::Graph as Graph>::VertexId>,
{
_phantom_data: PhantomData<&'graph ()>,
parent: Parent,
start: Iter,
}
impl<'graph, Parent, Iter> VertexIter<'graph, Parent, Iter>
where
Parent: VertexWalker<'graph>,
Iter: Iterator<Item = <Parent::Graph as Graph>::VertexId>,
{
pub fn new(parent: Parent, start: Iter) -> Self {
Self {
_phantom_data: Default::default(),
parent,
start,
}
}
}
impl<'graph, Parent, Iter> Walker<'graph> for VertexIter<'graph, Parent, Iter>
where
Parent: VertexWalker<'graph>,
Iter: Iterator<Item = <Parent::Graph as Graph>::VertexId>,
{
type Graph = Parent::Graph;
type Context = Parent::Context;
fn next_element(&mut self, graph: &'graph Self::Graph) -> Option<ElementId<Self::Graph>> {
self.next(graph).map(ElementId::Vertex)
}
fn ctx(&self) -> &Parent::Context {
self.parent.ctx()
}
fn ctx_mut(&mut self) -> &mut Self::Context {
self.parent.ctx_mut()
}
}
impl<'graph, Parent, Iter> VertexWalker<'graph> for VertexIter<'graph, Parent, Iter>
where
Parent: VertexWalker<'graph>,
Iter: Iterator<Item = <Parent::Graph as Graph>::VertexId>,
{
fn next(&mut self, _graph: &Self::Graph) -> Option<<Self::Graph as Graph>::VertexId> {
self.start.next()
}
}
impl<'graph, Mutability, Graph, Walker> VertexWalkerBuilder<'graph, Mutability, Graph, Walker>
where
Graph: crate::graph::Graph,
Walker: VertexWalker<'graph, Graph = Graph>,
{
/// # Vertices By ID Step
///
/// The `vertices_by_id` step allows you to begin a traversal from a specific set of vertex IDs.
/// This is useful when you already know the IDs of the vertices you want to include in your traversal.
///
/// ## Visual Diagram
///
/// Before vertices_by_id step (empty traversal):
/// ```text
/// [A] --- edge1 ---> [B] --- edge2 ---> [C]
/// ^
/// |
/// edge3
/// |
/// [D]
/// ```
///
/// After vertices_by_id step (with [id_A, id_C]):
/// ```text
/// [A]* --- edge1 ---> [B] --- edge2 ---> [C]*
/// ^
/// |
/// edge3
/// |
/// [D]
/// ```
///
/// ## Parameters
///
/// - `vertex_ids`: An iterator that yields vertex IDs to include in the traversal
///
/// ## Return Value
///
/// Returns a traversal containing all vertices with the specified IDs.
///
/// ## Example
///
/// ```rust
#[doc = function_body!("examples/vertices_by_id.rs", example, [])]
/// ```
///
/// For more examples, see the [vertices_by_id example](https://github.com/yourusername/graph-api/blob/main/graph-api-lib/examples/vertices_by_id.rs).
///
/// ## Notes
///
/// - This step is efficient when you already know the exact IDs of vertices you want to work with
/// - The order of vertices in the traversal will match the order of IDs in the input iterator
/// - For vertices that don't exist in the graph, they will be skipped without error
/// - This step is often used after a previous traversal has produced vertex IDs of interest
/// - When working with a large number of IDs, consider using a `HashSet` for deduplication if needed
pub fn vertices_by_id<Iter>(
self,
vertex_ids: Iter,
) -> VertexWalkerBuilder<'graph, Mutability, Graph, VertexIter<'graph, Walker, Iter::IntoIter>>
where
Iter: IntoIterator<Item = Graph::VertexId>,
{
self.with_vertex_walker(|walker| walker.vertices_by_id(vertex_ids))
}
}
impl<'graph, Graph, Mutability, Context> StartWalkerBuilder<'graph, Mutability, Graph, Context>
where
Graph: crate::graph::Graph,
Context: Clone + 'static,
{
pub fn vertices_by_id<Iter>(
self,
vertex_ids: Iter,
) -> VertexWalkerBuilder<
'graph,
Mutability,
Graph,
VertexIter<'graph, Empty<Graph, Context>, Iter::IntoIter>,
>
where
Iter: IntoIterator<Item = Graph::VertexId>,
{
crate::walker::builder::new(self.graph, self.empty.vertices_by_id(vertex_ids))
}
}