| 84 | /// returning a future that completes when all have been visited |
| 85 | template <typename T, typename Visitor> |
| 86 | Future<> VisitAsyncGenerator(AsyncGenerator<T> generator, Visitor visitor) { |
| 87 | struct LoopBody { |
| 88 | struct Callback { |
| 89 | Result<ControlFlow<>> operator()(const T& next) { |
| 90 | if (IsIterationEnd(next)) { |
| 91 | return Break(); |
| 92 | } else { |
| 93 | auto visited = visitor(next); |
| 94 | if (visited.ok()) { |
| 95 | return Continue(); |
| 96 | } else { |
| 97 | return visited; |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | Visitor visitor; |
| 103 | }; |
| 104 | |
| 105 | Future<ControlFlow<>> operator()() { |
| 106 | Callback callback{visitor}; |
| 107 | auto next = generator(); |
| 108 | return next.Then(std::move(callback)); |
| 109 | } |
| 110 | |
| 111 | AsyncGenerator<T> generator; |
| 112 | Visitor visitor; |
| 113 | }; |
| 114 | |
| 115 | return Loop(LoopBody{std::move(generator), std::move(visitor)}); |
| 116 | } |
| 117 | |
| 118 | /// \brief Wait for an async generator to complete, discarding results. |
| 119 | template <typename T> |