Mutate Step
The mutate step iterates over elements in the traversal, applying a callback function to each one. This callback receives mutable access to the graph, allowing for in-place modification of vertices or edges. mutate is a terminal step that consumes the walker and returns the total count (usize) of elements processed.
In this diagram:
- Input Elements: The walker starts with elements A, B, C, each having an initial value (e.g., 
val=1). - The 
.mutate(callback)step processes each element. The callback function has access to modify the graph. - Mutated Elements (In Graph): The diagram shows the state of the elements after the mutation callback has been applied (e.g., A' with 
val=10). This highlights the in-place nature of the operation. - Returns: usize: The step completes and returns the count of elements processed (3 in this case), terminating the walker chain.
 
Syntax
walker.mutate(|element, context, graph| {
    // mutation logic using graph access
})
Parameters
callback: A function that takes:- A reference to the current element (vertex or edge) - Note: Direct mutable access to the element itself might vary; mutation often happens via the 
graphreference using the element's ID. - The element's context
 - A mutable reference to the graph (
&mut G) - Performs modifications using the mutable graph reference (e.g., 
graph.vertex_mut(element.id())). 
- A reference to the current element (vertex or edge) - Note: Direct mutable access to the element itself might vary; mutation often happens via the 
 
Return Value
Returns a usize representing the number of elements processed by the mutate step.
Example
    // Example 1: Update all person vertices to increment their age
    println!("Incrementing age of all people:");
    // Print original ages
    graph
        .walk()
        .vertices(Vertex::person())
        .probe(|vertex, _| {
            if let Some(person) = vertex.project::<Person<_>>() {
                println!("  Before: {} is {} years old", person.name(), person.age());
            }
        })
        .count();
    // Perform the mutation - increment everyone's age by 1
    let updated_count = graph
        .walk_mut() // Must use walk_mut() for mutations
        .vertices(Vertex::person())
        .mutate(|graph, vertex_id, _| {
            // Note: updating requires cloning and replacing due to Rust's ownership model
            if let Some(mut vertex) = graph.vertex_mut(vertex_id) {
                if let Some(mut person) = vertex.project_mut::<PersonMut<_, _>>() {
                    // Increment the person age
                    person.set_age(person.age() + 1);
                }
            }
        });
    println!("  Updated {} person vertices", updated_count);
Best Practices
- Use 
mutatespecifically for modifying graph elements based on traversal results. - Access mutable elements via the provided 
graphreference and the element's ID (e.g.,graph.vertex_mut(id)). - Be mindful that mutations are applied directly and immediately to the graph state.
 - Consider using 
filterorcontrol_flowbeforemutateto precisely target which elements should be modified. - Understand the graph implementation's behavior regarding mutations during iteration (e.g., adding/removing elements might invalidate iterators in some graph types).
 
Common Use Cases
- Updating properties: Modifying attributes of vertices or edges (e.g., incrementing age, changing status).
 - Graph cleaning: Standardizing data or fixing inconsistencies found during traversal.
 - State transitions: Updating element states based on workflow logic during traversal.
 - Bulk updates: Applying a change to a set of elements identified by prior traversal steps.