pub struct EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Walker: EdgeWalker<'graph>,{ /* private fields */ }
Expand description
A builder for edge-focused graph traversals.
This builder constructs walkers that navigate graphs by moving along edges.
§Type Parameters
'graph
: The lifetime of the graph referenceMutability
: A marker type indicating whether graph mutations are allowedGraph
: The graph type being traversedWalker
: The edge walker implementation that will perform the traversal
Implementations§
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
Sourcepub fn graph(&mut self) -> &'graph Graph
pub fn graph(&mut self) -> &'graph Graph
Returns an immutable reference to the graph being traversed.
This consumes the graph reference, leaving the builder in a state where the graph reference has been taken.
§Returns
An immutable reference to the graph.
Sourcepub fn graph_mut(&mut self) -> &'graph mut Graph
pub fn graph_mut(&mut self) -> &'graph mut Graph
Sourcepub fn walker(self) -> Walker
pub fn walker(self) -> Walker
Consumes the builder and returns the underlying walker.
This extracts the walker from the builder, allowing it to be used directly.
§Returns
The walker that was being built.
Sourcepub fn with_edge_walker<EdgeWalker: EdgeWalker<'graph>, WithFn: FnOnce(Walker) -> EdgeWalker>(
self,
step: WithFn,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeWalker>
pub fn with_edge_walker<EdgeWalker: EdgeWalker<'graph>, WithFn: FnOnce(Walker) -> EdgeWalker>( self, step: WithFn, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeWalker>
Transforms the current walker into another edge walker.
This method allows for changing or extending the traversal using a transformation function applied to the current walker.
§Type Parameters
EdgeWalker
: The target edge walker typeWithFn
: A function type that converts the current walker
§Parameters
step
: The transformation function to apply
§Returns
A new edge walker builder containing the transformed walker
Sourcepub fn with_vertex_walker<VertexWalker: VertexWalker<'graph, Graph = Graph>, WithFn: FnOnce(Walker) -> VertexWalker>(
self,
step: WithFn,
) -> VertexWalkerBuilder<'graph, Mutability, Graph, VertexWalker>
pub fn with_vertex_walker<VertexWalker: VertexWalker<'graph, Graph = Graph>, WithFn: FnOnce(Walker) -> VertexWalker>( self, step: WithFn, ) -> VertexWalkerBuilder<'graph, Mutability, Graph, VertexWalker>
Transforms the current walker into a vertex walker.
This method allows for changing the traversal from edge-oriented to vertex-oriented by applying a transformation function to the current walker.
§Type Parameters
VertexWalker
: The target vertex walker typeWithFn
: A function type that converts the current walker
§Parameters
step
: The transformation function to apply
§Returns
A new vertex walker builder containing the transformed walker
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn collect<T: FromIterator<Graph::EdgeId>>(self) -> Twhere
Walker: EdgeWalker<'graph>,
pub fn collect<T: FromIterator<Graph::EdgeId>>(self) -> Twhere
Walker: EdgeWalker<'graph>,
Collects all edge IDs from this traversal into a collection of type T
.
This is a terminal operation that consumes the traversal.
See the documentation for VertexWalkerBuilder::collect
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
Sourcepub fn push_context<Callback, Context>(
self,
callback: Callback,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeContext<'graph, Walker, impl Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> ContextRef<Context, Walker::Context>, ContextRef<Context, Walker::Context>>>where
Callback: Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> Context,
Context: Clone + 'static,
pub fn push_context<Callback, Context>(
self,
callback: Callback,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeContext<'graph, Walker, impl Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> ContextRef<Context, Walker::Context>, ContextRef<Context, Walker::Context>>>where
Callback: Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> Context,
Context: Clone + 'static,
§Context Step
The push_context
step allows you to associate additional data with each edge in the traversal.
This is useful for carrying information along as you traverse, preserving state between traversal steps,
or accumulating results.
§Visual Diagram
Before push_context step (traversal with regular edges):
[Person A] --- created* ---> [Project X]
|
knows*
|
v
[Person B]
After push_context step (edges now have associated context data):
[Person A] --- created* + {type: "maintainer"} ---> [Project X]
|
knows* + {since: "2020"}
|
v
[Person B]
§Parameters
callback
: A function that takes the current edge and its existing context, and returns a new context value to associate with that edge
§Return Value
Returns a traversal with the same elements, but with additional context information attached to each edge.
§Example
// Walk the graph starting from the person vertex
let edge_types = graph
.walk()
.vertices_by_id(vec![person_id])
.edges(EdgeSearch::scan().outgoing())
.push_context(|edge, _ctx| {
// Determine edge type based on the edge type
let edge_type = match edge.weight() {
Edge::Created => "Created",
Edge::Knows { .. } => "Knows",
Edge::Language(_) => "Language",
};
// Return the edge type as context
edge_type
})
.map(|_v, c| *c)
.collect::<Vec<_>>();
println!("{:?}", edge_types);
§Notes
- Context is carried through the entire traversal, even across different graph elements
- Each push_context call creates a new context layer, with the previous context available as
ctx.parent()
- For complex traversals, you can build a nested context structure
- The context is cloned for each element, so keep context objects relatively small for performance
- Use
push_default_context()
for common patterns like storing the edge’s ID and data - When retrieving results, both the element and its context are returned in a tuple
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn control_flow<Predicate>(
self,
predicate: Predicate,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeControlFlow<'graph, Walker, Predicate>>where
Walker: 'graph,
for<'a> Predicate: Fn(&'a Graph::EdgeReference<'graph>, &mut Walker::Context) -> ControlFlow<Option<&'a Graph::EdgeReference<'graph>>, Option<&'a Graph::EdgeReference<'graph>>> + 'graph,
pub fn control_flow<Predicate>(
self,
predicate: Predicate,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeControlFlow<'graph, Walker, Predicate>>where
Walker: 'graph,
for<'a> Predicate: Fn(&'a Graph::EdgeReference<'graph>, &mut Walker::Context) -> ControlFlow<Option<&'a Graph::EdgeReference<'graph>>, Option<&'a Graph::EdgeReference<'graph>>> + 'graph,
§ControlFlow Step
The control_flow
step allows you to evaluate each edge with a predicate function that returns a
std::ops::ControlFlow
value. This gives precise control over traversal - you can either:
- Continue and include the element (ControlFlow::Continue(Some(id)))
- Continue but skip the element (ControlFlow::Continue(None))
- Stop traversal with an optional final element (ControlFlow::Break(option))
§Visual Diagram
Before control_flow step (all edges in traversal):
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns*
|
[Company]
After control_flow step that only includes “knows” edges and breaks on old connections:
[Person A] --- knows* ---> [Person B] --- created ---> [Project]
^
|
owns
|
[Company]
§Parameters
predicate
: A function that takes a reference to an edge and a mutable reference to its context, and returns astd::ops::ControlFlow<Option<EdgeId>, Option<EdgeId>>
value:- Return
ControlFlow::Continue(Some(edge.id()))
to include the edge and continue - Return
ControlFlow::Continue(None)
to skip the edge and continue - Return
ControlFlow::Break(Some(edge.id()))
to include the edge and stop traversal - Return
ControlFlow::Break(None)
to stop traversal without including the edge
- Return
§Return Value
A new walker that applies the control flow logic to the traversal.
§Example
// Use control_flow to skip edges (None), include them (Some), or stop traversal (Break)
let early_connection = graph
.walk()
.vertices_by_id(vec![start_id])
.edges(EdgeSearch::scan())
.control_flow(|edge, _| {
if let Edge::Knows { since } = edge.weight() {
// If we found a connection from before 2010, stop traversal
if *since < 2010 {
println!(
"Found a very old connection ({}), stopping traversal",
since
);
return ControlFlow::Break(Some(edge));
}
// Include 'knows' edges
return ControlFlow::Continue(Some(edge));
}
// Skip non-'knows' edges
ControlFlow::Continue(None)
})
.first();
match early_connection {
Some(id) => println!("Old connection {:?}", id),
None => println!("No connections found"),
}
§Notes
- This step is more powerful than
filter()
as it can both filter elements and control traversal flow - The predicate receives a mutable reference to the context, allowing you to update state during traversal
- Use this step when you need a combination of filtering and conditional stopping of traversal
- Only elements where the predicate returns
Some
will be included in the traversal - When
ControlFlow::Break
is returned, the entire traversal stops immediately
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn count(self) -> usizewhere
'graph: 'graph,
pub fn count(self) -> usizewhere
'graph: 'graph,
Counts the total number of edges in this traversal.
This is a terminal operation that consumes the traversal.
See the documentation for VertexWalkerBuilder::count
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn dbg(
self,
tag: &'static str,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, impl FnMut(&Graph::EdgeReference<'_>, &Walker::Context)>>
pub fn dbg( self, tag: &'static str, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, impl FnMut(&Graph::EdgeReference<'_>, &Walker::Context)>>
§Debug Step
Prints edges as they are traversed through the graph, making it easier to debug complex traversals.
See the documentation for VertexWalkerBuilder::dbg
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
Sourcepub fn push_default_context(
self,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeContext<'graph, Walker, impl Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> ContextRef<DefaultEdgeContext<Graph::EdgeId, Graph::Edge>, Walker::Context>, ContextRef<DefaultEdgeContext<Graph::EdgeId, Graph::Edge>, Walker::Context>>>
pub fn push_default_context( self, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeContext<'graph, Walker, impl Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> ContextRef<DefaultEdgeContext<Graph::EdgeId, Graph::Edge>, Walker::Context>, ContextRef<DefaultEdgeContext<Graph::EdgeId, Graph::Edge>, Walker::Context>>>
§Default Context Step
A specialized version of the push_context
step for edges that automatically
stores the current edge’s ID and data in the context.
See the documentation for VertexWalkerBuilder::push_default_context
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
<Walker as Walker<'graph>>::Context: Clone + 'static,
Sourcepub fn filter<Predicate>(
self,
predicate: Predicate,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeFilter<'graph, Walker, Predicate>>
pub fn filter<Predicate>( self, predicate: Predicate, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeFilter<'graph, Walker, Predicate>>
§Filter Step
The filter
step allows you to keep only edges that match a predicate function.
Edges that don’t match the predicate are excluded from further traversal.
§Visual Diagram
Before filter step (all edges in traversal):
[Person A] --- knows(2018)* ---> [Person B] --- created(2022)* ---> [Project]
^
|
owns(2020)*
|
[Company C]
After filter(year >= 2020) step (only recent edges remain in traversal):
[Person A] --- knows(2018) ---> [Person B] --- created(2022)* ---> [Project]
^
|
owns(2020)*
|
[Company C]
§Parameters
predicate
: A function that takes a reference to an edge and its context, and returns a boolean. Only edges for which this function returnstrue
will be included in the traversal.
§Return Value
A new walker containing only the edges that matched the predicate.
§Example
// Filter edges to find relationships created in a specific year
let recent_connections = graph
.walk()
.vertices_by_id(vec![start_id])
.edges(EdgeSearch::scan())
.filter(|edge, _| {
if let Edge::Knows { since } = edge.weight() {
*since >= 2020
} else {
false
}
})
.count();
println!("Found {} connections made since 2020", recent_connections);
§Notes
- The filter step does not modify the graph, only the traversal
- For complex filtering logic, consider breaking into multiple filter steps for better readability
- Use pattern matching to work with different edge types
- The filter is applied lazily during traversal, not when the step is added to the walker
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn first(self) -> Option<Graph::EdgeId>
pub fn first(self) -> Option<Graph::EdgeId>
§First Step
The first
step retrieves only the first edge from a traversal and terminates.
This is a terminal operation that consumes the walker and returns an Option containing
the first edge ID if one exists, or None if the traversal is empty.
§Visual Diagram
Before first step (multiple edges in traversal):
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns*
|
[Company]
After first step (only first edge returned):
[Person A] --- knows* ---> [Person B] --- created ---> [Project]
^
|
owns
|
[Company]
Result: knows
§Parameters
None
§Return Value
Option<EdgeId>
- Returns Some(id) with the first edge ID if the traversal contains at least one edge,
or None if the traversal is empty.
§Example
// Get the first "Created" edge in the graph
let first_created = graph
.walk()
.vertices(VertexSearch::scan())
.filter_person() // Start with person vertices
.edges(EdgeSearch::scan())
.filter(|e, _| matches!(e.weight(), Edge::Created))
.first();
// If found, print relationship information
if let Some(edge_id) = first_created {
if let Some(edge) = graph.edge(edge_id) {
let source = graph.vertex(edge.tail()).unwrap();
let target = graph.vertex(edge.head()).unwrap();
println!(
"Found first 'Created' relationship: {:?} -> {:?}",
source.id(),
target.id()
);
}
} else {
println!("No 'Created' relationships found");
}
§Notes
- Efficient for finding the first matching edge in a graph
- Particularly useful for checking existence of specific relationship types
- Often used with filtering to find specific types of edges
- Returns immediately after finding the first edge, improving performance for large graphs
- After getting the edge ID, you can use graph.edge() to access the full edge data
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
pub fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
§Fold Step
Accumulates a result by processing each edge in the traversal.
See the documentation for VertexWalkerBuilder::fold
for more details.
§Example
// Working with edges - find the earliest relationship year
let earliest_relation = graph
.walk()
.vertices(Vertex::person())
.edges(Edge::knows())
.fold(None, |earliest, edge, _| {
if let Edge::Knows { since } = edge.weight() {
match earliest {
None => Some(*since),
Some(year) if *since < year => Some(*since),
_ => earliest,
}
} else {
earliest
}
});
// There should be at least one relationship in our test graph
assert!(earliest_relation.is_some());
if let Some(year) = earliest_relation {
println!("Earliest relationship started in: {}", year);
}
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn head(
self,
) -> VertexWalkerBuilder<'graph, Mutability, Graph, Endpoints<'graph, Walker>>
pub fn head( self, ) -> VertexWalkerBuilder<'graph, Mutability, Graph, Endpoints<'graph, Walker>>
§Head Step
The head
step transforms an edge traversal into a vertex traversal by moving to the
head vertex of each edge. In graph theory, the head is the destination/target vertex that
the edge point to.
§Visual Diagram
Before head step (with edges as current elements):
[A] --- edge1* ---> [B] --- edge2* ---> [C]
^
|
edge3*
|
[D]
After head step (moved to target vertices of edges):
[A]* --- edge1 ---> [B]* --- edge2 ---> [C]*
^
|
edge3
|
[D]
§Parameters
None
§Return Value
A vertex walker that will traverse the destination/target vertices of the edges from the previous step.
§Example
// Find all people who created projects
// The head() step returns the source vertices of edges
let creators = graph
.walk()
.vertices(Vertex::project())
.edges(Edge::created().incoming())
.head()
.collect::<Vec<_>>();
// There should be at least one creator
assert!(!creators.is_empty());
// Find vertices connected to graph_api project
let connected_to_graph_api = graph
.walk()
.vertices_by_id(vec![graph_api_id])
.edges(EdgeSearch::scan().incoming())
.head()
.collect::<Vec<_>>();
// There should be at least one vertex connected to graph_api
assert!(!connected_to_graph_api.is_empty());
§Notes
- The
head
step can only be used after an edge traversal step - Transforms the traversal type from EdgeWalker to VertexWalker
- For directed graphs, head refers to the destination/target vertex
- For undirected graphs, the distinction between head and tail may depend on implementation
- Commonly used in conjunction with incoming edges to find vertices that point to certain destinations
- The head-tail terminology follows standard graph theory convention
- When working with edges, remember that
head()
gives you “where the edge points to” (destination)
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn map<R, M>(self, mapping: M) -> impl Iterator<Item = R> + 'graph
pub fn map<R, M>(self, mapping: M) -> impl Iterator<Item = R> + 'graph
§Map Step
The map
step transforms edges in the traversal by applying a mapping function to each edge.
It returns an iterator that yields the transformed elements, allowing you to convert edge data
into any desired format.
§Visual Diagram
Before map step (with edges in traversal):
[Person A] --- knows(2018)* ---> [Person B] --- created(2022)* ---> [Project]
^
|
owns(2020)*
|
[Company]
After map step with edge -> relationship description
:
"knows since 2018", "created in 2022", "owns since 2020"
§Parameters
mapping
: A function that takes an edge reference and context, and returns a transformed value. The function signature isFnMut(Graph::EdgeReference<'graph>, Walker::Context) -> R
.
§Return Value
Returns an iterator that yields the transformed elements, with the type determined by the return type of the mapping function.
§Example
// Map edges to relationship information
let relationships: Vec<String> = graph
.walk()
.vertices_by_id(vec![start_id])
.edges(EdgeSearch::scan())
.map(|edge, _| {
// Create a descriptive string for each relationship
match edge.weight() {
Edge::Knows { since } => format!("Knows since {}", since),
Edge::Created => "Created".to_string(),
Edge::Language(lang) => format!("Uses language {}", lang.name),
}
})
.collect();
// Print the relationships
println!("\nRelationships from starting vertex:");
for relationship in &relationships {
println!("- {}", relationship);
}
§Notes
- Perfect for extracting relationship data (e.g., edge types, weights, or properties)
- Use pattern matching to handle different edge types appropriately
- You can access connected vertices through the edge’s tail() and head() methods
- For analyzing graph connectivity, pair with edge-traversal steps like filter
- The iterator chain can continue with standard Rust iterator methods after mapping
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn mutate<Callback>(self, callback: Callback) -> usize
pub fn mutate<Callback>(self, callback: Callback) -> usize
§Mutate Step
Allows you to modify the graph during edge traversal.
See the documentation for VertexWalkerBuilder::mutate
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn mutate_context<Callback>(
self,
callback: Callback,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeMutateContext<'graph, Walker, Callback>>
pub fn mutate_context<Callback>( self, callback: Callback, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeMutateContext<'graph, Walker, Callback>>
§Mutate Context Step
The mutate_context
step allows you to modify the context during edge traversal. For each edge
in the traversal, the provided callback function is executed, giving you the ability to modify
the current context object in-place.
§Visual Diagram
Before mutate_context step (traversal with contexts):
[Person A] --- knows* + {weight: 1} ---> [Person B]
After mutate_context step (contexts have been modified):
[Person A] --- knows* + {weight: 2} ---> [Person B]
§Parameters
callback
: A function that receives:- The current edge reference
- A mutable reference to the current context
§Return Value
Returns a traversal with the same elements, but with modified context values.
§Example
// Use mutate_context to track each edge in the traversal
let ctx = graph
.walk()
.vertices_by_id(vec![start_id])
.push_context(|_, _| 0)
.edges(EdgeSearch::scan().outgoing())
.mutate_context(move |_, ctx| {
// Count each edge we encounter
**ctx += 1;
})
.map(|_, ctx| *ctx)
.last()
.expect("Expected to process at least one edge");
println!("Total edges traversed: {}", ctx);
assert_eq!(ctx, 2, "Should have traversed two edges");
§Notes
See the documentation for VertexWalkerBuilder::mutate_context
for more details.
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn probe<Callback>(
self,
callback: Callback,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, Callback>>
pub fn probe<Callback>( self, callback: Callback, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, Callback>>
§Probe Step
The probe
step allows you to execute a callback function for each edge in the traversal
without altering the traversal itself. This is useful for debugging, analyzing connections,
or collecting edge statistics during a traversal.
§Visual Diagram
Before probe step:
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns*
|
[Company]
After probe step (unchanged, but callback executed for each edge *):
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns*
|
[Company]
§Parameters
callback
: A function that takes a reference to the current edge being traversed, and optionally the current context. The function signature can be either:FnMut(&Graph::EdgeReference<'_>, &Context)
- Probe with access to current context
§Return Value
A walker of the same type as the input with the probe operation added to the pipeline, allowing for further chaining of operations.
§Example
// Use probe to analyze edges during traversal
graph
.walk()
.vertices_by_id(vec![bryn_id])
.edges(EdgeSearch::scan())
.probe(|edge, _| {
// Print information about each edge without affecting traversal
println!(
"Found edge: {:?} connecting {:?} to {:?}",
edge.weight(),
graph.vertex(edge.tail()).unwrap().id(),
graph.vertex(edge.head()).unwrap().id()
);
})
.count();
§Notes
- The
probe
step does not modify the traversal path or edges - The callback function is executed for each edge as it’s traversed
- When using the context variant, you can access traversal context data during probing
- Useful for analyzing connection patterns without modifying the traversal
- Consider using pattern matching in the callback to handle different edge types
- You can use endpoint accessors like
tail()
andhead()
to inspect connected vertices - Context access is especially useful when combined with
push_context
steps earlier in the traversal
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph + 'graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph + 'graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn reduce<Reducer>(
self,
reducer: Reducer,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeReduce<'graph, Walker, Reducer>>where
Reducer: for<'a> Fn(&'a Graph::EdgeReference<'graph>, &'a Graph::EdgeReference<'graph>, &Walker::Context) -> &'a Graph::EdgeReference<'graph>,
pub fn reduce<Reducer>(
self,
reducer: Reducer,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeReduce<'graph, Walker, Reducer>>where
Reducer: for<'a> Fn(&'a Graph::EdgeReference<'graph>, &'a Graph::EdgeReference<'graph>, &Walker::Context) -> &'a Graph::EdgeReference<'graph>,
§Reduce Step
Combines edges in the traversal using a reducer function, with the first edge as the initial accumulator.
§Visual Diagram
Before reduce step (traversal position on edges):
[A] --- edge1* ---> [B] --- edge2* ---> [C]
^
|
edge3*
|
[D]
After reduce step (a single edge containing the combined result):
[Source] --- [Result]* ---> [Target] --- ... ---> [More Traversal Steps]
§Parameters
reducer
: A closure that takes:- The current accumulated edge (left)
- The next edge to combine (right)
- The parent walker’s context (passed through)
- Returns either the left or right edge to continue the reduction
§Return Value
Returns a walker containing a single edge representing the final reduced value. If the input traversal is empty, the walker will yield nothing.
§Example
// Find the edge with the highest "since" value between two edges
let oldest_edge = graph
.walk()
.vertices(VertexSearch::scan())
.filter_person()
.edges(EdgeSearch::scan())
.filter_knows()
.reduce(|acc, edge, _ctx| {
let acc_since = acc.project::<Knows<_>>().unwrap().since();
let edge_since = edge.project::<Knows<_>>().unwrap().since();
if edge_since > acc_since { edge } else { acc }
})
.map(|edge, _ctx| {
let since = edge.project::<Knows<_>>().unwrap().since();
format!(
"The edge with latest 'since' value is {:?}, since {}",
edge.id(),
since
)
})
.next()
.expect("should have got a result");
println!("{}", oldest_edge);
§Notes
- The reduce step is a non-terminal operation - it can be chained with other operations
- The walker will yield a single edge - the final result of combining all input edges
- If the traversal is empty, the walker will yield nothing
- The first element serves as the initial accumulator value
- The reducer function must return a reference to one of the two input elements
- The returned element becomes the new accumulator for the next reduction step
- The reducer function operates on the elements only, the context remains unchanged
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn tail(
self,
) -> VertexWalkerBuilder<'graph, Mutability, Graph, Endpoints<'graph, Walker>>
pub fn tail( self, ) -> VertexWalkerBuilder<'graph, Mutability, Graph, Endpoints<'graph, Walker>>
§Tail Step
The tail
step transforms an edge traversal into a vertex traversal by moving to the
tail vertex of each edge. In graph theory, the tail is the source/origin vertex
that the edge comes from.
§Visual Diagram
Before tail step (with edges as current elements):
[A] --- edge1* ---> [B] --- edge2* ---> [C]
^
|
edge3*
|
[D]
After tail step (moved to source vertices of edges):
[A]* --- edge1 ---> [B]* --- edge2 ---> [C]
^
|
edge3
|
[D]*
§Parameters
None
§Return Value
A vertex walker that will traverse the source vertices of the edges from the previous step.
§Example
// Find all projects created by bryn
// The tail() step returns the target vertices of edges
let projects = graph
.walk()
.vertices_by_id(vec![bryn_id])
.edges(Edge::created())
.tail()
.collect::<Vec<_>>();
// Bryn should have created at least one project
assert!(!projects.is_empty());
// Find all friends of bryn (people they know)
let friends = graph
.walk()
.vertices_by_id(vec![bryn_id])
.edges(Edge::knows())
.tail()
.collect::<Vec<_>>();
// Bryn should know at least one person
assert!(!friends.is_empty());
For more examples, see the tail example.
§Notes
- The
tail
step can only be used after an edge traversal step - Transforms the traversal type from EdgeWalker to VertexWalker
- For directed graphs, tail refers to the source/origin vertex
- For undirected graphs, the distinction between head and tail may depend on implementation
- Commonly used in conjunction with
edges
to follow relationships - The head-tail terminology follows standard graph theory convention
- When working with edges, remember that
tail()
gives you “where the edge comes from” (source)
Source§impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>where
Graph: Graph,
Walker: EdgeWalker<'graph, Graph = Graph>,
Sourcepub fn take(
self,
n: usize,
) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeTake<'graph, Walker>>
pub fn take( self, n: usize, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeTake<'graph, Walker>>
§Take Step
The take
step restricts an edge traversal to return at most a specified number of edges.
This is useful for pagination, performance optimization, or when you only need a subset of edges.
§Visual Diagram
Before take step (with multiple edges in traversal):
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns*
|
[Company]
After take(2) step (only first 2 edges remain in traversal):
[Person A] --- knows* ---> [Person B] --- created* ---> [Project]
^
|
owns
|
[Company]
§Parameters
n
: A usize value specifying the maximum number of edges to include in the traversal
§Return Value
Returns a traversal containing at most the specified number of edges.
§Example
// Get at most 3 edges connected to a specific vertex
let connections = graph
.walk()
.vertices_by_id(vec![start_id])
.edges(EdgeSearch::scan())
.take(3) // Only process three edges, even if there are more
.collect::<Vec<_>>();
// Verify we got at most 3 edges
println!("Retrieved {} connections (limited to 3)", connections.len());
§Notes
- Use take to avoid processing excessive numbers of connections in a dense graph
- Improves performance for graphs with highly connected nodes
- Particularly useful when you only need to analyze a sample of connections
- The order of edges returned depends on the graph implementation
- For pagination purposes, consider combining with sorting or other ordering mechanisms
- Follows the naming convention of Rust’s standard library Iterator::take