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}