graph_api_lib/walker/builder.rs
1use crate::walker::steps::Empty;
2use crate::walker::{EdgeWalker, VertexWalker};
3use std::marker::PhantomData;
4
5/// A marker trait for types that can be mutated.
6///
7/// This trait is used to differentiate between mutable and immutable graph walkers.
8pub trait Mutable {}
9
10/// A marker type that indicates mutability.
11///
12/// Used as a type parameter in walker builders to enable mutable graph operations.
13pub struct MutableMarker;
14
15impl Mutable for MutableMarker {}
16
17/// A marker type that indicates immutability.
18///
19/// Used as a type parameter in walker builders to restrict operations to immutable ones.
20pub struct ImmutableMarker;
21
22/// Manages access to a graph during traversal operations.
23///
24/// This enum represents the three states of graph access:
25/// - Immutable: A shared reference to the graph
26/// - Mutable: An exclusive reference to the graph
27/// - Taken: The reference has been consumed
28#[derive(Default)]
29pub enum GraphAccess<'graph, Graph> {
30 /// A shared reference to a graph
31 Immutable(&'graph Graph),
32 /// An exclusive reference to a graph
33 Mutable(&'graph mut Graph),
34 /// The reference has been taken and can no longer be used
35 #[default]
36 Taken,
37}
38
39impl<'graph, Graph> GraphAccess<'graph, Graph> {
40 /// Takes the graph reference, leaving the enum in the `Taken` state.
41 ///
42 /// # Returns
43 /// A shared reference to the graph.
44 ///
45 /// # Panics
46 /// Panics if the graph reference has already been taken.
47 pub fn take(&mut self) -> &'graph Graph {
48 match std::mem::take(self) {
49 GraphAccess::Immutable(graph) => graph,
50 GraphAccess::Mutable(graph) => graph,
51 GraphAccess::Taken => panic!("graph already taken"),
52 }
53 }
54
55 /// Takes the graph reference for mutation, leaving the enum in the `Taken` state.
56 ///
57 /// # Returns
58 /// An exclusive reference to the graph.
59 ///
60 /// # Panics
61 /// Panics if the graph reference has already been taken or if it's an immutable reference.
62 pub fn take_mut(&mut self) -> &'graph mut Graph {
63 match std::mem::take(self) {
64 GraphAccess::Immutable(_) => {
65 panic!("graph should not have been accessed mutably")
66 }
67 GraphAccess::Mutable(graph) => graph,
68 GraphAccess::Taken => panic!("graph already taken"),
69 }
70 }
71}
72
73/// A generic builder for graph walkers.
74///
75/// This builder is used to construct and compose graph traversal operations.
76///
77/// # Type Parameters
78/// - `'graph`: The lifetime of the graph reference
79/// - `Mutability`: A marker type indicating whether graph mutations are allowed
80/// - `Graph`: The graph type being traversed
81/// - `Walker`: The walker implementation that will perform the traversal
82pub struct WalkerBuilder<'graph, Mutability, Graph, Walker>
83where
84 Walker: crate::walker::Walker<'graph>,
85{
86 pub(crate) _phantom: PhantomData<&'graph (Mutability, Graph, Walker)>,
87 pub(crate) walker: Walker,
88}
89
90impl<'graph, Mutability, Graph, Walker> WalkerBuilder<'graph, Mutability, Graph, Walker>
91where
92 Walker: crate::walker::Walker<'graph>,
93{
94 /// Returns a mutable reference to the underlying walker.
95 ///
96 /// This method provides access to the walker being built, allowing for direct manipulation.
97 ///
98 /// # Returns
99 /// A mutable reference to the walker.
100 pub fn walker(&mut self) -> &mut Walker {
101 &mut self.walker
102 }
103}
104
105impl<'graph, Mutability, Graph, Walker> From<VertexWalkerBuilder<'graph, Mutability, Graph, Walker>>
106 for WalkerBuilder<'graph, Mutability, Graph, Walker>
107where
108 Walker: VertexWalker<'graph, Graph = Graph>,
109{
110 fn from(value: VertexWalkerBuilder<'graph, Mutability, Graph, Walker>) -> Self {
111 WalkerBuilder {
112 _phantom: Default::default(),
113 walker: value.walker,
114 }
115 }
116}
117
118impl<'graph, Mutability, Graph, Walker> From<EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>>
119 for WalkerBuilder<'graph, Mutability, Graph, Walker>
120where
121 Walker: EdgeWalker<'graph, Graph = Graph>,
122{
123 fn from(value: EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>) -> Self {
124 WalkerBuilder {
125 _phantom: Default::default(),
126 walker: value.walker,
127 }
128 }
129}
130
131/// A builder for vertex-focused graph traversals.
132///
133/// This builder constructs walkers that navigate graphs by moving from vertex to vertex.
134///
135/// # Type Parameters
136/// - `'graph`: The lifetime of the graph reference
137/// - `Mutability`: A marker type indicating whether graph mutations are allowed
138/// - `Graph`: The graph type being traversed
139/// - `Walker`: The vertex walker implementation that will perform the traversal
140pub struct VertexWalkerBuilder<'graph, Mutability, Graph, Walker>
141where
142 Walker: VertexWalker<'graph, Graph = Graph>,
143{
144 _phantom: PhantomData<&'graph Mutability>,
145 walker: Walker,
146 graph: GraphAccess<'graph, Graph>,
147}
148
149pub(crate) fn new<'graph, Mutability, Graph, Start>(
150 graph: GraphAccess<'graph, Graph>,
151 start: Start,
152) -> VertexWalkerBuilder<'graph, Mutability, Graph, Start>
153where
154 Graph: crate::graph::Graph,
155 Start: VertexWalker<'graph, Graph = Graph>,
156{
157 VertexWalkerBuilder {
158 _phantom: Default::default(),
159 walker: start,
160 graph,
161 }
162}
163
164#[allow(dead_code)]
165pub(crate) fn new_mut<'graph, Graph, Start>(
166 graph: &'graph mut Graph,
167 start: Start,
168) -> VertexWalkerBuilder<'graph, MutableMarker, Graph, Start>
169where
170 Graph: crate::graph::Graph,
171 Start: VertexWalker<'graph, Graph = Graph>,
172{
173 VertexWalkerBuilder {
174 _phantom: Default::default(),
175 walker: start,
176 graph: GraphAccess::Mutable(graph),
177 }
178}
179
180impl<'graph, Mutability, Graph, Walker> VertexWalkerBuilder<'graph, Mutability, Graph, Walker>
181where
182 Graph: crate::graph::Graph,
183 Walker: VertexWalker<'graph, Graph = Graph>,
184{
185 /// Returns an immutable reference to the graph being traversed.
186 ///
187 /// This consumes the graph reference, leaving the builder in a state
188 /// where the graph reference has been taken.
189 ///
190 /// # Returns
191 /// An immutable reference to the graph.
192 pub fn graph(&mut self) -> &'graph Graph {
193 self.graph.take()
194 }
195
196 /// Returns a mutable reference to the graph being traversed.
197 ///
198 /// This consumes the graph reference, leaving the builder in a state
199 /// where the graph reference has been taken.
200 ///
201 /// # Returns
202 /// A mutable reference to the graph.
203 ///
204 /// # Panics
205 /// Panics if the graph was not accessed mutably or has already been taken.
206 pub fn graph_mut(&mut self) -> &'graph mut Graph {
207 self.graph.take_mut()
208 }
209
210 /// Consumes the builder and returns the underlying walker.
211 ///
212 /// This extracts the walker from the builder, allowing it to be used directly.
213 ///
214 /// # Returns
215 /// The walker that was being built.
216 pub fn walker(self) -> Walker {
217 self.walker
218 }
219
220 /// Transforms the current vertex walker into an edge walker.
221 ///
222 /// This method allows for changing the traversal from vertex-oriented to edge-oriented
223 /// by applying a transformation function to the current walker.
224 ///
225 /// # Type Parameters
226 /// - `EdgeWalker`: The target edge walker type
227 /// - `WithFn`: A function type that converts the current walker to an edge walker
228 ///
229 /// # Parameters
230 /// - `step`: The transformation function to apply
231 ///
232 /// # Returns
233 /// A new edge walker builder containing the transformed walker
234 pub fn with_edge_walker<
235 EdgeWalker: crate::walker::EdgeWalker<'graph>,
236 WithFn: FnOnce(Walker) -> EdgeWalker,
237 >(
238 self,
239 step: WithFn,
240 ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeWalker> {
241 EdgeWalkerBuilder {
242 _phantom: Default::default(),
243 walker: step(self.walker),
244 graph: self.graph,
245 }
246 }
247
248 /// Transforms the current vertex walker into another vertex walker.
249 ///
250 /// This method allows for changing or extending the traversal while remaining
251 /// vertex-oriented by applying a transformation function to the current walker.
252 ///
253 /// # Type Parameters
254 /// - `VertexWalker`: The target vertex walker type
255 /// - `WithFn`: A function type that converts the current walker to another vertex walker
256 ///
257 /// # Parameters
258 /// - `step`: The transformation function to apply
259 ///
260 /// # Returns
261 /// A new vertex walker builder containing the transformed walker
262 pub fn with_vertex_walker<
263 VertexWalker: crate::walker::VertexWalker<'graph, Graph = Graph>,
264 WithFn: FnOnce(Walker) -> VertexWalker,
265 >(
266 self,
267 step: WithFn,
268 ) -> VertexWalkerBuilder<'graph, Mutability, Graph, VertexWalker> {
269 VertexWalkerBuilder {
270 _phantom: Default::default(),
271 walker: step(self.walker),
272 graph: self.graph,
273 }
274 }
275}
276
277/// A builder for edge-focused graph traversals.
278///
279/// This builder constructs walkers that navigate graphs by moving along edges.
280///
281/// # Type Parameters
282/// - `'graph`: The lifetime of the graph reference
283/// - `Mutability`: A marker type indicating whether graph mutations are allowed
284/// - `Graph`: The graph type being traversed
285/// - `Walker`: The edge walker implementation that will perform the traversal
286pub struct EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
287where
288 Walker: EdgeWalker<'graph>,
289{
290 _phantom: PhantomData<&'graph Mutability>,
291 walker: Walker,
292 graph: GraphAccess<'graph, Graph>,
293}
294
295impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
296where
297 Graph: crate::graph::Graph,
298 Walker: EdgeWalker<'graph, Graph = Graph>,
299 <Walker as crate::walker::Walker<'graph>>::Context: Clone + 'static,
300{
301 /// Returns an immutable reference to the graph being traversed.
302 ///
303 /// This consumes the graph reference, leaving the builder in a state
304 /// where the graph reference has been taken.
305 ///
306 /// # Returns
307 /// An immutable reference to the graph.
308 pub fn graph(&mut self) -> &'graph Graph {
309 self.graph.take()
310 }
311
312 /// Returns a mutable reference to the graph being traversed.
313 ///
314 /// This consumes the graph reference, leaving the builder in a state
315 /// where the graph reference has been taken.
316 ///
317 /// # Returns
318 /// A mutable reference to the graph.
319 ///
320 /// # Panics
321 /// Panics if the graph was not accessed mutably or has already been taken.
322 pub fn graph_mut(&mut self) -> &'graph mut Graph {
323 self.graph.take_mut()
324 }
325
326 /// Consumes the builder and returns the underlying walker.
327 ///
328 /// This extracts the walker from the builder, allowing it to be used directly.
329 ///
330 /// # Returns
331 /// The walker that was being built.
332 pub fn walker(self) -> Walker {
333 self.walker
334 }
335
336 /// Transforms the current walker into another edge walker.
337 ///
338 /// This method allows for changing or extending the traversal using
339 /// a transformation function applied to the current walker.
340 ///
341 /// # Type Parameters
342 /// - `EdgeWalker`: The target edge walker type
343 /// - `WithFn`: A function type that converts the current walker
344 ///
345 /// # Parameters
346 /// - `step`: The transformation function to apply
347 ///
348 /// # Returns
349 /// A new edge walker builder containing the transformed walker
350 pub fn with_edge_walker<
351 EdgeWalker: crate::walker::EdgeWalker<'graph>,
352 WithFn: FnOnce(Walker) -> EdgeWalker,
353 >(
354 self,
355 step: WithFn,
356 ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeWalker> {
357 EdgeWalkerBuilder {
358 _phantom: Default::default(),
359 walker: step(self.walker),
360 graph: self.graph,
361 }
362 }
363
364 /// Transforms the current walker into a vertex walker.
365 ///
366 /// This method allows for changing the traversal from edge-oriented to vertex-oriented
367 /// by applying a transformation function to the current walker.
368 ///
369 /// # Type Parameters
370 /// - `VertexWalker`: The target vertex walker type
371 /// - `WithFn`: A function type that converts the current walker
372 ///
373 /// # Parameters
374 /// - `step`: The transformation function to apply
375 ///
376 /// # Returns
377 /// A new vertex walker builder containing the transformed walker
378 pub fn with_vertex_walker<
379 VertexWalker: crate::walker::VertexWalker<'graph, Graph = Graph>,
380 WithFn: FnOnce(Walker) -> VertexWalker,
381 >(
382 self,
383 step: WithFn,
384 ) -> VertexWalkerBuilder<'graph, Mutability, Graph, VertexWalker> {
385 VertexWalkerBuilder {
386 _phantom: Default::default(),
387 walker: step(self.walker),
388 graph: self.graph,
389 }
390 }
391}
392
393pub(crate) fn new_start<Graph>(graph: &Graph) -> StartWalkerBuilder<'_, ImmutableMarker, Graph, ()>
394where
395 Graph: crate::graph::Graph,
396{
397 StartWalkerBuilder {
398 _phantom: Default::default(),
399 graph: GraphAccess::Immutable(graph),
400 empty: Empty::default(),
401 }
402}
403
404pub(crate) fn new_start_mut<Graph>(
405 graph: &mut Graph,
406) -> StartWalkerBuilder<'_, MutableMarker, Graph, ()>
407where
408 Graph: crate::graph::Graph,
409{
410 StartWalkerBuilder {
411 _phantom: Default::default(),
412 graph: GraphAccess::Mutable(graph),
413 empty: Empty::default(),
414 }
415}
416
417/// The initial builder for starting a graph traversal.
418///
419/// This builder is the entry point for creating graph traversals. It contains
420/// a reference to the graph and an empty context, and provides methods to begin
421/// traversing the graph.
422///
423/// # Type Parameters
424/// - `'graph`: The lifetime of the graph reference
425/// - `Mutability`: A marker type indicating whether graph mutations are allowed
426/// - `Graph`: The graph type being traversed
427/// - `Context`: The initial context type for the traversal
428pub struct StartWalkerBuilder<'graph, Mutability, Graph, Context> {
429 pub(crate) _phantom: PhantomData<&'graph (Mutability, Graph)>,
430 pub(crate) graph: GraphAccess<'graph, Graph>,
431 pub(crate) empty: Empty<Graph, Context>,
432}