graph_api_lib/walker/steps/
map.rs

1use crate::walker::builder::{EdgeWalkerBuilder, VertexWalkerBuilder};
2use crate::walker::steps::into_iter::{EdgeReferenceIterImpl, VertexReferenceIterImpl};
3use crate::walker::{EdgeWalker, VertexWalker};
4use include_doc::function_body;
5
6impl<'graph, Mutability, Graph, Walker> VertexWalkerBuilder<'graph, Mutability, Graph, Walker>
7where
8    Graph: crate::graph::Graph,
9    Walker: VertexWalker<'graph, Graph = Graph>,
10{
11    /// # Map Step
12    ///
13    /// The `map` step transforms vertices in the traversal by applying a mapping function to each vertex.
14    /// Unlike other steps that continue the traversal chain, `map` returns an iterator that yields the
15    /// transformed elements directly.
16    ///
17    /// ## Visual Diagram
18    ///
19    /// Before map step:
20    /// ```text
21    ///   [Project A]* --- created_by ---> [Person B]* --- owns ---> [Project C]*  
22    ///    ^                                         
23    ///    |                                         
24    ///   uses                                       
25    ///    |                                         
26    ///   [Project D]*                                        
27    /// ```
28    ///
29    /// After map step with `vertex -> extract project name`:
30    /// ```text
31    ///   "Project A", "Person B", "Project C", "Project D"
32    /// ```
33    ///
34    /// ## Parameters
35    ///
36    /// - `mapping`: A function that takes a vertex reference and context, and returns a transformed value.
37    ///   The function signature is `FnMut(Graph::VertexReference<'graph>, Walker::Context) -> R`.
38    ///
39    /// ## Return Value
40    ///
41    /// Returns an iterator that yields the transformed elements. The type of the iterator items
42    /// is determined by the return type of the mapping function.
43    ///
44    /// ## Example
45    ///
46    /// ```rust
47    #[doc = function_body!("examples/map.rs", vertex_example, [])]
48    /// ```
49    ///
50    /// ## Notes
51    ///
52    /// - The `map` step is terminal - it returns an iterator, not a traversal builder
53    /// - The mapping function has access to both the vertex and its context
54    /// - After mapping, you can continue with standard Rust iterator operations like filter or collect
55    /// - Common uses include extracting properties from vertices (e.g., names, IDs, attributes)
56    /// - For building complex data structures, consider using pattern matching in the mapping function
57    /// - To map vertices with context data, use `push_context` before mapping
58    pub fn map<R, M>(mut self, mut mapping: M) -> impl Iterator<Item = R> + 'graph
59    where
60        M: FnMut(Graph::VertexReference<'graph>, Walker::Context) -> R + 'graph,
61        Walker: 'graph,
62    {
63        VertexReferenceIterImpl::new(self.graph(), self.walker())
64            .map(move |(reference, ctx)| mapping(reference, ctx))
65    }
66}
67
68impl<'graph, Mutability, Graph, Walker> EdgeWalkerBuilder<'graph, Mutability, Graph, Walker>
69where
70    Graph: crate::graph::Graph,
71    Walker: EdgeWalker<'graph, Graph = Graph>,
72{
73    /// # Map Step
74    ///
75    /// The `map` step transforms edges in the traversal by applying a mapping function to each edge.
76    /// It returns an iterator that yields the transformed elements, allowing you to convert edge data
77    /// into any desired format.
78    ///
79    /// ## Visual Diagram
80    ///
81    /// Before map step (with edges in traversal):
82    /// ```text
83    ///   [Person A] --- knows(2018)* ---> [Person B] --- created(2022)* ---> [Project]
84    ///    ^                                         
85    ///    |                                         
86    ///   owns(2020)*                                       
87    ///    |                                         
88    ///   [Company]                                        
89    /// ```
90    ///
91    /// After map step with `edge -> relationship description`:
92    /// ```text
93    ///   "knows since 2018", "created in 2022", "owns since 2020"
94    /// ```
95    ///
96    /// ## Parameters
97    ///
98    /// - `mapping`: A function that takes an edge reference and context, and returns a transformed value.
99    ///   The function signature is `FnMut(Graph::EdgeReference<'graph>, Walker::Context) -> R`.
100    ///
101    /// ## Return Value
102    ///
103    /// Returns an iterator that yields the transformed elements, with the type determined by
104    /// the return type of the mapping function.
105    ///
106    /// ## Example
107    ///
108    /// ```rust
109    #[doc = function_body!("examples/map.rs", edge_example, [])]
110    /// ```
111    ///
112    /// ## Notes
113    ///
114    /// - Perfect for extracting relationship data (e.g., edge types, weights, or properties)
115    /// - Use pattern matching to handle different edge types appropriately
116    /// - You can access connected vertices through the edge's tail() and head() methods
117    /// - For analyzing graph connectivity, pair with edge-traversal steps like filter
118    /// - The iterator chain can continue with standard Rust iterator methods after mapping
119    pub fn map<R, M>(mut self, mut mapping: M) -> impl Iterator<Item = R> + 'graph
120    where
121        M: FnMut(Graph::EdgeReference<'graph>, Walker::Context) -> R + 'graph,
122        Walker: 'graph,
123    {
124        EdgeReferenceIterImpl::new(self.graph(), self.walker())
125            .map(move |(reference, ctx)| mapping(reference, ctx))
126    }
127}