1use core::{convert::Infallible, marker::PhantomData, ops::ControlFlow};
2
3use crate::{
4 body::admit::{Finished, Open, Track},
5 decode::{exec, request},
6};
7
8pub mod admit;
9pub mod body;
10pub mod open;
11mod uniform;
12
13pub use uniform::Uniform;
14
15pub struct Uniforms<P>(PhantomData<fn() -> P>);
16
17pub trait Set {
19 type SyncOpen;
20 type SyncFinished;
21 type TaskOpen;
22 type TaskFinished;
23 type DuplexOpen;
24 type DuplexFinished;
25 type UnsupportedOpen;
26 type UnsupportedFinished;
27}
28
29pub enum Routed {}
31
32impl Set for Routed {
33 type SyncOpen = Track<Open>;
34 type SyncFinished = Track<Finished>;
35 type TaskOpen = Track<Open>;
36 type TaskFinished = Track<Finished>;
37 type DuplexOpen = ();
38 type DuplexFinished = ();
39 type UnsupportedOpen = Track<Open>;
40 type UnsupportedFinished = Track<Finished>;
41}
42
43pub enum Admitted {}
45
46impl Set for Admitted {
47 type SyncOpen = Track<Open>;
48 type SyncFinished = Track<Finished>;
49 type TaskOpen = Track<Open>;
50 type TaskFinished = Track<Finished>;
51 type DuplexOpen = ();
52 type DuplexFinished = ();
53 type UnsupportedOpen = Track<Open>;
54 type UnsupportedFinished = Track<Finished>;
55}
56
57pub trait Finish: Set {
62 fn sync(body: Self::SyncOpen) -> Self::SyncFinished;
63
64 fn task(body: Self::TaskOpen) -> Self::TaskFinished;
65
66 fn duplex(body: Self::DuplexOpen) -> Self::DuplexFinished;
67
68 fn reject(body: Self::UnsupportedOpen) -> Self::UnsupportedFinished;
69}
70
71pub trait Slot<P>: Sized {
73 fn prepare(self) -> P;
74
75 fn admit<K, B>(self, body: B) -> request::Admitted<K, P, B> {
76 request::Admitted::new(self.prepare(), body)
77 }
78}
79
80pub struct Whole<P>(P);
81
82impl<P> Whole<P> {
83 pub const fn new(prep: P) -> Self {
84 Self(prep)
85 }
86}
87
88impl<P> Slot<P> for Whole<P> {
89 fn prepare(self) -> P {
90 self.0
91 }
92}
93
94pub trait Map<P, F: Set, G: Set>: Sized {
96 type Break;
97 type Retained;
98
99 fn sync_open<S: Slot<P>>(
100 self,
101 slot: S,
102 body: F::SyncOpen,
103 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::SyncOpen)>;
104
105 fn sync_done<S: Slot<P>>(
106 self,
107 slot: S,
108 body: F::SyncFinished,
109 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::SyncFinished)>;
110
111 fn task_open<S: Slot<P>>(
112 self,
113 slot: S,
114 body: F::TaskOpen,
115 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::TaskOpen)>;
116
117 fn task_done<S: Slot<P>>(
118 self,
119 slot: S,
120 body: F::TaskFinished,
121 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::TaskFinished)>;
122
123 fn duplex_open<S: Slot<P>>(
124 self,
125 slot: S,
126 body: F::DuplexOpen,
127 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::DuplexOpen)>;
128
129 fn duplex_done<S: Slot<P>>(
130 self,
131 slot: S,
132 body: F::DuplexFinished,
133 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::DuplexFinished)>;
134
135 fn reject_open<S: Slot<P>>(
136 self,
137 slot: S,
138 body: F::UnsupportedOpen,
139 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::UnsupportedOpen)>;
140
141 fn reject_done<S: Slot<P>>(
142 self,
143 slot: S,
144 body: F::UnsupportedFinished,
145 ) -> ControlFlow<Self::Break, (Self::Retained, S, G::UnsupportedFinished)>;
146}
147
148pub struct Pass;
150
151impl<P, F, G> Map<P, F, G> for Pass
152where
153 F: Set,
154 G: Set<
155 SyncOpen = F::SyncOpen,
156 SyncFinished = F::SyncFinished,
157 TaskOpen = F::TaskOpen,
158 TaskFinished = F::TaskFinished,
159 DuplexOpen = F::DuplexOpen,
160 DuplexFinished = F::DuplexFinished,
161 UnsupportedOpen = F::UnsupportedOpen,
162 UnsupportedFinished = F::UnsupportedFinished,
163 >,
164{
165 type Break = Infallible;
166 type Retained = ();
167
168 fn sync_open<S: Slot<P>>(
169 self,
170 slot: S,
171 body: F::SyncOpen,
172 ) -> ControlFlow<Infallible, ((), S, F::SyncOpen)> {
173 ControlFlow::Continue(((), slot, body))
174 }
175
176 fn sync_done<S: Slot<P>>(
177 self,
178 slot: S,
179 body: F::SyncFinished,
180 ) -> ControlFlow<Infallible, ((), S, F::SyncFinished)> {
181 ControlFlow::Continue(((), slot, body))
182 }
183
184 fn task_open<S: Slot<P>>(
185 self,
186 slot: S,
187 body: F::TaskOpen,
188 ) -> ControlFlow<Infallible, ((), S, F::TaskOpen)> {
189 ControlFlow::Continue(((), slot, body))
190 }
191
192 fn task_done<S: Slot<P>>(
193 self,
194 slot: S,
195 body: F::TaskFinished,
196 ) -> ControlFlow<Infallible, ((), S, F::TaskFinished)> {
197 ControlFlow::Continue(((), slot, body))
198 }
199
200 fn duplex_open<S: Slot<P>>(
201 self,
202 slot: S,
203 body: F::DuplexOpen,
204 ) -> ControlFlow<Infallible, ((), S, F::DuplexOpen)> {
205 ControlFlow::Continue(((), slot, body))
206 }
207
208 fn duplex_done<S: Slot<P>>(
209 self,
210 slot: S,
211 body: F::DuplexFinished,
212 ) -> ControlFlow<Infallible, ((), S, F::DuplexFinished)> {
213 ControlFlow::Continue(((), slot, body))
214 }
215
216 fn reject_open<S: Slot<P>>(
217 self,
218 slot: S,
219 body: F::UnsupportedOpen,
220 ) -> ControlFlow<Infallible, ((), S, F::UnsupportedOpen)> {
221 ControlFlow::Continue(((), slot, body))
222 }
223
224 fn reject_done<S: Slot<P>>(
225 self,
226 slot: S,
227 body: F::UnsupportedFinished,
228 ) -> ControlFlow<Infallible, ((), S, F::UnsupportedFinished)> {
229 ControlFlow::Continue(((), slot, body))
230 }
231}
232
233pub trait Each<P, F: Set>: Sized {
235 type Output<'a>;
236
237 fn sync_open<'a, S: Slot<P>>(self, slot: &S, body: &'a mut F::SyncOpen) -> Self::Output<'a>;
238
239 fn sync_done<'a, S: Slot<P>>(self, slot: &S, body: &'a mut F::SyncFinished)
240 -> Self::Output<'a>;
241
242 fn task_open<'a, S: Slot<P>>(self, slot: &S, body: &'a mut F::TaskOpen) -> Self::Output<'a>;
243
244 fn task_done<'a, S: Slot<P>>(self, slot: &S, body: &'a mut F::TaskFinished)
245 -> Self::Output<'a>;
246
247 fn duplex_open<'a, S: Slot<P>>(self, slot: &S, body: &'a mut F::DuplexOpen)
248 -> Self::Output<'a>;
249
250 fn duplex_done<'a, S: Slot<P>>(
251 self,
252 slot: &S,
253 body: &'a mut F::DuplexFinished,
254 ) -> Self::Output<'a>;
255
256 fn reject_open<'a, S: Slot<P>>(
257 self,
258 slot: &S,
259 body: &'a mut F::UnsupportedOpen,
260 ) -> Self::Output<'a>;
261
262 fn reject_done<'a, S: Slot<P>>(
263 self,
264 slot: &S,
265 body: &'a mut F::UnsupportedFinished,
266 ) -> Self::Output<'a>;
267}
268
269pub trait Fold<P, F: Set>: Sized {
274 type Output;
275
276 fn sync_open<S: Slot<P>>(self, slot: S, body: F::SyncOpen) -> Self::Output;
277
278 fn sync_done<S: Slot<P>>(self, slot: S, body: F::SyncFinished) -> Self::Output;
279
280 fn task_open<S: Slot<P>>(self, slot: S, body: F::TaskOpen) -> Self::Output;
281
282 fn task_done<S: Slot<P>>(self, slot: S, body: F::TaskFinished) -> Self::Output;
283
284 fn duplex_open<S: Slot<P>>(self, slot: S, body: F::DuplexOpen) -> Self::Output;
285
286 fn duplex_done<S: Slot<P>>(self, slot: S, body: F::DuplexFinished) -> Self::Output;
287
288 fn reject_open<S: Slot<P>>(self, slot: S, body: F::UnsupportedOpen) -> Self::Output;
289
290 fn reject_done<S: Slot<P>>(self, slot: S, body: F::UnsupportedFinished) -> Self::Output;
291}
292
293pub trait Family<P>: Sized {
295 type State<F: Set>: Flow<P, F, Family = Self> + body::Flow<F>;
296}
297
298pub trait Homogeneous<P, K: exec::Kind>: Family<P> {
303 fn fold<F, T>(state: Self::State<F>, fold: T) -> T::Output
304 where
305 F: Set,
306 T: exec::Fold<P, F, K>;
307}
308
309impl<P> Family<P> for Uniforms<P> {
310 type State<F: Set> = Uniform<P, F>;
311}
312
313impl<P> Homogeneous<P, exec::Sync> for Uniforms<P> {
314 fn fold<F, T>(state: Uniform<P, F>, fold: T) -> T::Output
315 where
316 F: Set,
317 T: exec::Fold<P, F, exec::Sync>,
318 {
319 let (prep, body) = state.into_parts();
320 match body {
321 request::Body::Open(body) => fold.open(Whole::new(prep), body),
322 request::Body::Finished(body) => fold.finished(Whole::new(prep), body),
323 }
324 }
325}
326
327type Mapped<B, R, S, P, G> = ControlFlow<B, (R, <S as Family<P>>::State<G>)>;
328
329pub trait Flow<P, F: Set>: Sized {
331 type Family: Family<P>;
332
333 fn each<'a, M: Each<P, F>>(&'a mut self, each: M) -> M::Output<'a>;
334
335 fn map_retain<G: Set, M: Map<P, F, G>>(
336 self,
337 map: M,
338 ) -> Mapped<M::Break, M::Retained, Self::Family, P, G>;
339
340 fn map<G: Set, M: Map<P, F, G, Retained = ()>>(
341 self,
342 map: M,
343 ) -> ControlFlow<M::Break, <Self::Family as Family<P>>::State<G>> {
344 self.map_retain(map).map_continue(|((), state)| state)
345 }
346
347 fn fold<T: Fold<P, F>>(self, fold: T) -> T::Output;
348
349 fn finish(self) -> Result<Self, Self>
352 where
353 F: Finish;
354
355 fn each_open<'a, V: open::Each<F>>(&'a mut self, visit: V) -> V::Output<'a>
356 where
357 F: open::Set;
358
359 fn fold_open<V: open::Fold<P, F>>(self, visit: V) -> V::Output
360 where
361 F: open::Set;
362
363 fn consume<O, V: FnOnce(F::Body) -> O>(self, visit: V) -> O
364 where
365 F: open::Set;
366}
367
368pub trait Admission<P, F: Set, G: Set>: Sized {
370 type Output;
371
372 fn admit<V: admit::Visit<P, F, G>>(self, visit: &mut V) -> ControlFlow<V::Break, Self::Output>;
373}