1use core::{convert::Infallible, ops::ControlFlow};
2
3use crate::decode::{dispatch, state};
4
5type Decision<T, C, E, S> =
6 ControlFlow<Result<T, (dispatch::Error<E, Infallible, Infallible>, C)>, S>;
7
8pub trait Visit<P, F: state::Set, G: state::Set> {
10 type Break;
11
12 fn sync_open<S: state::Slot<P>>(
13 &mut self,
14 slot: S,
15 body: F::SyncOpen,
16 ) -> ControlFlow<Self::Break, (S, G::SyncOpen)>;
17
18 fn sync_done<S: state::Slot<P>>(
19 &mut self,
20 slot: S,
21 body: F::SyncFinished,
22 ) -> ControlFlow<Self::Break, (S, G::SyncFinished)>;
23
24 fn task_open<S: state::Slot<P>>(
25 &mut self,
26 slot: S,
27 body: F::TaskOpen,
28 ) -> ControlFlow<Self::Break, (S, G::TaskOpen)>;
29
30 fn task_done<S: state::Slot<P>>(
31 &mut self,
32 slot: S,
33 body: F::TaskFinished,
34 ) -> ControlFlow<Self::Break, (S, G::TaskFinished)>;
35
36 fn duplex_open<S: state::Slot<P>>(
37 &mut self,
38 slot: S,
39 body: F::DuplexOpen,
40 ) -> ControlFlow<Self::Break, (S, G::DuplexOpen)>;
41
42 fn duplex_done<S: state::Slot<P>>(
43 &mut self,
44 slot: S,
45 body: F::DuplexFinished,
46 ) -> ControlFlow<Self::Break, (S, G::DuplexFinished)>;
47
48 fn reject_open<S: state::Slot<P>>(
49 &mut self,
50 slot: S,
51 body: F::UnsupportedOpen,
52 ) -> ControlFlow<Self::Break, (S, G::UnsupportedOpen)>;
53
54 fn reject_done<S: state::Slot<P>>(
55 &mut self,
56 slot: S,
57 body: F::UnsupportedFinished,
58 ) -> ControlFlow<Self::Break, (S, G::UnsupportedFinished)>;
59}
60
61pub trait TryVisit<P, F: state::Set, G: state::Set, E> {
63 type Break<T, C>;
64
65 fn sync_open<S: state::Slot<P>, C, T>(
66 &mut self,
67 flow: Decision<T, C, E, S>,
68 body: F::SyncOpen,
69 ) -> ControlFlow<Self::Break<T, C>, (S, G::SyncOpen)>;
70
71 fn sync_done<S: state::Slot<P>, C, T>(
72 &mut self,
73 flow: Decision<T, C, E, S>,
74 body: F::SyncFinished,
75 ) -> ControlFlow<Self::Break<T, C>, (S, G::SyncFinished)>;
76
77 fn task_open<S: state::Slot<P>, C, T>(
78 &mut self,
79 flow: Decision<T, C, E, S>,
80 body: F::TaskOpen,
81 ) -> ControlFlow<Self::Break<T, C>, (S, G::TaskOpen)>;
82
83 fn task_done<S: state::Slot<P>, C, T>(
84 &mut self,
85 flow: Decision<T, C, E, S>,
86 body: F::TaskFinished,
87 ) -> ControlFlow<Self::Break<T, C>, (S, G::TaskFinished)>;
88
89 fn duplex_open<S: state::Slot<P>, C, T>(
90 &mut self,
91 flow: Decision<T, C, E, S>,
92 body: F::DuplexOpen,
93 ) -> ControlFlow<Self::Break<T, C>, (S, G::DuplexOpen)>;
94
95 fn duplex_done<S: state::Slot<P>, C, T>(
96 &mut self,
97 flow: Decision<T, C, E, S>,
98 body: F::DuplexFinished,
99 ) -> ControlFlow<Self::Break<T, C>, (S, G::DuplexFinished)>;
100
101 fn reject_open<S: state::Slot<P>, C, T>(
102 &mut self,
103 flow: Decision<T, C, E, S>,
104 body: F::UnsupportedOpen,
105 ) -> ControlFlow<Self::Break<T, C>, (S, G::UnsupportedOpen)>;
106
107 fn reject_done<S: state::Slot<P>, C, T>(
108 &mut self,
109 flow: Decision<T, C, E, S>,
110 body: F::UnsupportedFinished,
111 ) -> ControlFlow<Self::Break<T, C>, (S, G::UnsupportedFinished)>;
112}
113
114impl<P> Visit<P, state::Routed, state::Admitted> for state::Pass {
115 type Break = Infallible;
116
117 fn sync_open<S: state::Slot<P>>(
118 &mut self,
119 slot: S,
120 body: <state::Routed as state::Set>::SyncOpen,
121 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::SyncOpen)> {
122 ControlFlow::Continue((slot, body))
123 }
124
125 fn sync_done<S: state::Slot<P>>(
126 &mut self,
127 slot: S,
128 body: <state::Routed as state::Set>::SyncFinished,
129 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::SyncFinished)> {
130 ControlFlow::Continue((slot, body))
131 }
132
133 fn task_open<S: state::Slot<P>>(
134 &mut self,
135 slot: S,
136 body: <state::Routed as state::Set>::TaskOpen,
137 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::TaskOpen)> {
138 ControlFlow::Continue((slot, body))
139 }
140
141 fn task_done<S: state::Slot<P>>(
142 &mut self,
143 slot: S,
144 body: <state::Routed as state::Set>::TaskFinished,
145 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::TaskFinished)> {
146 ControlFlow::Continue((slot, body))
147 }
148
149 fn duplex_open<S: state::Slot<P>>(
150 &mut self,
151 slot: S,
152 body: <state::Routed as state::Set>::DuplexOpen,
153 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::DuplexOpen)> {
154 ControlFlow::Continue((slot, body))
155 }
156
157 fn duplex_done<S: state::Slot<P>>(
158 &mut self,
159 slot: S,
160 body: <state::Routed as state::Set>::DuplexFinished,
161 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::DuplexFinished)> {
162 ControlFlow::Continue((slot, body))
163 }
164
165 fn reject_open<S: state::Slot<P>>(
166 &mut self,
167 slot: S,
168 body: <state::Routed as state::Set>::UnsupportedOpen,
169 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::UnsupportedOpen)> {
170 ControlFlow::Continue((slot, body))
171 }
172
173 fn reject_done<S: state::Slot<P>>(
174 &mut self,
175 slot: S,
176 body: <state::Routed as state::Set>::UnsupportedFinished,
177 ) -> ControlFlow<Self::Break, (S, <state::Admitted as state::Set>::UnsupportedFinished)> {
178 ControlFlow::Continue((slot, body))
179 }
180}
181
182impl<P, E> TryVisit<P, state::Routed, state::Admitted, E> for state::Pass {
183 type Break<T, C> = Result<T, (dispatch::Error<E, Infallible, Infallible>, C)>;
184
185 fn sync_open<S: state::Slot<P>, C, T>(
186 &mut self,
187 flow: ControlFlow<Self::Break<T, C>, S>,
188 body: <state::Routed as state::Set>::SyncOpen,
189 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::SyncOpen)> {
190 flow.map_continue(|slot| (slot, body))
191 }
192
193 fn sync_done<S: state::Slot<P>, C, T>(
194 &mut self,
195 flow: ControlFlow<Self::Break<T, C>, S>,
196 body: <state::Routed as state::Set>::SyncFinished,
197 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::SyncFinished)> {
198 flow.map_continue(|slot| (slot, body))
199 }
200
201 fn task_open<S: state::Slot<P>, C, T>(
202 &mut self,
203 flow: ControlFlow<Self::Break<T, C>, S>,
204 body: <state::Routed as state::Set>::TaskOpen,
205 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::TaskOpen)> {
206 flow.map_continue(|slot| (slot, body))
207 }
208
209 fn task_done<S: state::Slot<P>, C, T>(
210 &mut self,
211 flow: ControlFlow<Self::Break<T, C>, S>,
212 body: <state::Routed as state::Set>::TaskFinished,
213 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::TaskFinished)> {
214 flow.map_continue(|slot| (slot, body))
215 }
216
217 fn duplex_open<S: state::Slot<P>, C, T>(
218 &mut self,
219 flow: ControlFlow<Self::Break<T, C>, S>,
220 body: <state::Routed as state::Set>::DuplexOpen,
221 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::DuplexOpen)> {
222 flow.map_continue(|slot| (slot, body))
223 }
224
225 fn duplex_done<S: state::Slot<P>, C, T>(
226 &mut self,
227 flow: ControlFlow<Self::Break<T, C>, S>,
228 body: <state::Routed as state::Set>::DuplexFinished,
229 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::DuplexFinished)> {
230 flow.map_continue(|slot| (slot, body))
231 }
232
233 fn reject_open<S: state::Slot<P>, C, T>(
234 &mut self,
235 flow: ControlFlow<Self::Break<T, C>, S>,
236 body: <state::Routed as state::Set>::UnsupportedOpen,
237 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::UnsupportedOpen)> {
238 flow.map_continue(|slot| (slot, body))
239 }
240
241 fn reject_done<S: state::Slot<P>, C, T>(
242 &mut self,
243 flow: ControlFlow<Self::Break<T, C>, S>,
244 body: <state::Routed as state::Set>::UnsupportedFinished,
245 ) -> ControlFlow<Self::Break<T, C>, (S, <state::Admitted as state::Set>::UnsupportedFinished)>
246 {
247 flow.map_continue(|slot| (slot, body))
248 }
249}