turbo_tasks/graph/
visit.rs1use std::{future::Future, iter::Map};
2
3use anyhow::Result;
4use tracing::Span;
5
6use super::VisitControlFlow;
7
8pub trait Visit<Node, Edge = (), Impl = ()> {
11 type EdgesIntoIter: IntoIterator<Item = (Node, Edge)>;
12 type EdgesFuture: Future<Output = Result<Self::EdgesIntoIter>> + Send;
13
14 fn visit(&mut self, node: &Node, edge: Option<&Edge>) -> VisitControlFlow {
20 let _ = node;
21 let _ = edge;
22 VisitControlFlow::Continue
23 }
24
25 fn edges(&mut self, node: &Node) -> Self::EdgesFuture;
33
34 fn span(&mut self, _node: &Node, _edge: Option<&Edge>) -> Span {
36 Span::none()
37 }
38}
39
40pub struct ImplWithEdgeRef;
46
47impl<Node, Edge, VisitFn, NeighFut, NeighIt> Visit<Node, Edge, ImplWithEdgeRef> for VisitFn
48where
49 VisitFn: FnMut(&Node) -> NeighFut,
50 NeighFut: Future<Output = Result<NeighIt>> + Send,
51 NeighIt: IntoIterator<Item = (Node, Edge)>,
52{
53 type EdgesIntoIter = NeighIt;
54 type EdgesFuture = NeighFut;
55
56 fn edges(&mut self, node: &Node) -> Self::EdgesFuture {
57 (self)(node)
58 }
59}
60
61pub struct ImplWithEdgeValue;
62
63impl<Node, Edge, VisitFn, NeighFut, NeighIt> Visit<Node, Edge, ImplWithEdgeValue> for VisitFn
64where
65 Node: Clone,
66 VisitFn: FnMut(Node) -> NeighFut,
67 NeighFut: Future<Output = Result<NeighIt>> + Send,
68 NeighIt: IntoIterator<Item = (Node, Edge)>,
69{
70 type EdgesIntoIter = NeighIt;
71 type EdgesFuture = NeighFut;
72
73 fn edges(&mut self, node: &Node) -> Self::EdgesFuture {
74 (self)(node.clone())
75 }
76}
77
78pub struct ImplRef;
79
80impl<Node, VisitFn, NeighFut, NeighIt> Visit<Node, (), ImplRef> for VisitFn
81where
82 VisitFn: FnMut(&Node) -> NeighFut,
83 NeighFut: Future<Output = Result<NeighIt>> + Send,
84 NeighIt: IntoIterator<Item = Node>,
85{
86 type EdgesIntoIter = Map<NeighIt::IntoIter, fn(Node) -> (Node, ())>;
87 type EdgesFuture = NoEdgeFuture<NeighFut>;
88
89 fn edges(&mut self, node: &Node) -> Self::EdgesFuture {
90 NoEdgeFuture((self)(node))
91 }
92}
93
94pub struct ImplValue;
95
96impl<Node, VisitFn, NeighFut, NeighIt> Visit<Node, (), ImplValue> for VisitFn
97where
98 Node: Clone,
99 VisitFn: FnMut(Node) -> NeighFut,
100 NeighFut: Future<Output = Result<NeighIt>> + Send,
101 NeighIt: IntoIterator<Item = Node>,
102{
103 type EdgesIntoIter = Map<NeighIt::IntoIter, fn(Node) -> (Node, ())>;
104 type EdgesFuture = NoEdgeFuture<NeighFut>;
105
106 fn edges(&mut self, node: &Node) -> Self::EdgesFuture {
107 NoEdgeFuture((self)(node.clone()))
108 }
109}
110
111pub struct NoEdgeFuture<F>(F);
112
113impl<F, Node, NeighIt> Future for NoEdgeFuture<F>
114where
115 F: Future<Output = Result<NeighIt>> + Send,
116 NeighIt: IntoIterator<Item = Node>,
117{
118 type Output = Result<Map<NeighIt::IntoIter, fn(Node) -> (Node, ())>>;
119
120 fn poll(
121 self: std::pin::Pin<&mut Self>,
122 cx: &mut std::task::Context<'_>,
123 ) -> std::task::Poll<Self::Output> {
124 let future = unsafe { self.map_unchecked_mut(|s| &mut s.0) };
125 future.poll(cx).map(|res| {
126 res.map(|it| {
127 fn map_fn<Node>(node: Node) -> (Node, ()) {
128 (node, ())
129 }
130 let f: fn(Node) -> (Node, ()) = map_fn;
131 it.into_iter().map(f)
132 })
133 })
134 }
135}