Struct EdgeWalkerBuilder

Source
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 reference
  • Mutability: A marker type indicating whether graph mutations are allowed
  • Graph: The graph type being traversed
  • Walker: 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,

Source

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.

Source

pub fn graph_mut(&mut self) -> &'graph mut Graph

Returns a mutable 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

A mutable reference to the graph.

§Panics

Panics if the graph was not accessed mutably or has already been taken.

Source

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.

Source

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 type
  • WithFn: 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

Source

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 type
  • WithFn: 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>,

Source

pub fn collect<T: FromIterator<Graph::EdgeId>>(self) -> T
where 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,

Source

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>,

Source

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 a std::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 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>,

Source

pub fn count(self) -> usize
where '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>,

Source

pub fn dbg( self, tag: &'static str, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, impl FnMut(&Graph::EdgeReference<'_>, &Walker::Context)>>
where Walker::Context: Debug,

§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,

Source

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>>>
where Graph::Edge: Clone + 'static,

§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,

Source

pub fn filter<Predicate>( self, predicate: Predicate, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeFilter<'graph, Walker, Predicate>>
where Predicate: Fn(&Graph::EdgeReference<'_>, &Walker::Context) -> bool,

§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 returns true 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>,

Source

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>,

Source

pub fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
where F: FnMut(Acc, Graph::EdgeReference<'graph>, &Walker::Context) -> Acc, 'graph: 'graph,

§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>,

Source

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>,

Source

pub fn map<R, M>(self, mapping: M) -> impl Iterator<Item = R> + 'graph
where M: FnMut(Graph::EdgeReference<'graph>, Walker::Context) -> R + 'graph, Walker: '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 is FnMut(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>,

Source

pub fn mutate<Callback>(self, callback: Callback) -> usize
where Callback: Fn(&mut Walker::Graph, Graph::EdgeId, &Walker::Context), Mutability: Mutable, 'graph: 'graph,

§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>,

Source

pub fn mutate_context<Callback>( self, callback: Callback, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeMutateContext<'graph, Walker, Callback>>
where Callback: Fn(&Graph::EdgeReference<'_>, &mut Walker::Context) + 'graph,

§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>,

Source

pub fn probe<Callback>( self, callback: Callback, ) -> EdgeWalkerBuilder<'graph, Mutability, Graph, EdgeProbe<'graph, Walker, Callback>>
where Callback: FnMut(&Graph::EdgeReference<'_>, &Walker::Context),

§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() and head() 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>,

Source

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>,

Source

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>,

Source

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

Trait Implementations§

Source§

impl<'graph, Mutability, Graph, Walker> From<EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>> for WalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: EdgeWalker<'graph, Graph = Graph>,

Source§

fn from(value: EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>) -> Self

Converts to this type from the input type.
Source§

impl<'graph, Mutability, Graph, Walker> IntoIterator for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Graph: Graph, Walker: EdgeWalker<'graph, Graph = Graph>,

Source§

type Item = <Graph as Graph>::EdgeId

The type of the elements being iterated over.
Source§

type IntoIter = EdgeIterImpl<'graph, Graph, Walker>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

impl<'graph, Mutability, Graph, Walker> Freeze for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: Freeze,

§

impl<'graph, Mutability, Graph, Walker> RefUnwindSafe for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: RefUnwindSafe, Mutability: RefUnwindSafe, Graph: RefUnwindSafe,

§

impl<'graph, Mutability, Graph, Walker> Send for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: Send, Mutability: Sync, Graph: Sync + Send,

§

impl<'graph, Mutability, Graph, Walker> Sync for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: Sync, Mutability: Sync, Graph: Sync,

§

impl<'graph, Mutability, Graph, Walker> Unpin for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
where Walker: Unpin,

§

impl<'graph, Mutability, Graph, Walker> !UnwindSafe for EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.