Skip to main content

sark_core/decode/state/
uniform.rs

1use core::ops::ControlFlow;
2
3use crate::{
4    body::admit::{Finished, Open, Track},
5    decode::{
6        exec, request,
7        state::{
8            Admission, Admitted, Each, Finish, Flow, Fold, Map, Set, Slot, Uniforms, Whole, admit,
9            body, open,
10        },
11    },
12};
13
14/// One-route representation with no route discriminant.
15pub struct Uniform<P, F: Set> {
16    slot: Whole<P>,
17    body: request::Body<F::SyncOpen, F::SyncFinished>,
18}
19
20impl<P, F: Set> Uniform<P, F> {
21    pub const fn new(prep: P, body: request::Body<F::SyncOpen, F::SyncFinished>) -> Self {
22        Self {
23            slot: Whole::new(prep),
24            body,
25        }
26    }
27
28    pub(super) fn into_parts(self) -> (P, request::Body<F::SyncOpen, F::SyncFinished>) {
29        (self.slot.0, self.body)
30    }
31}
32
33impl<P> Uniform<P, Admitted> {
34    pub fn into_request(self) -> AdmittedBody<P> {
35        match self.body {
36            request::Body::Open(body) => request::Body::Open(self.slot.admit(body)),
37            request::Body::Finished(body) => request::Body::Finished(self.slot.admit(body)),
38        }
39    }
40}
41
42impl<P, F: Set> Flow<P, F> for Uniform<P, F> {
43    type Family = Uniforms<P>;
44
45    fn each<'a, M: Each<P, F>>(&'a mut self, each: M) -> M::Output<'a> {
46        match &mut self.body {
47            request::Body::Open(body) => each.sync_open(&self.slot, body),
48            request::Body::Finished(body) => each.sync_done(&self.slot, body),
49        }
50    }
51
52    fn map_retain<G: Set, M: Map<P, F, G>>(
53        self,
54        map: M,
55    ) -> ControlFlow<M::Break, (M::Retained, Uniform<P, G>)> {
56        let (retained, slot, body) = match self.body {
57            request::Body::Open(body) => {
58                let (retained, slot, body) = map.sync_open(self.slot, body)?;
59                (retained, slot, request::Body::Open(body))
60            }
61            request::Body::Finished(body) => {
62                let (retained, slot, body) = map.sync_done(self.slot, body)?;
63                (retained, slot, request::Body::Finished(body))
64            }
65        };
66        ControlFlow::Continue((retained, Uniform { slot, body }))
67    }
68
69    fn fold<T: Fold<P, F>>(self, fold: T) -> T::Output {
70        match self.body {
71            request::Body::Open(body) => fold.sync_open(self.slot, body),
72            request::Body::Finished(body) => fold.sync_done(self.slot, body),
73        }
74    }
75
76    fn finish(self) -> Result<Self, Self>
77    where
78        F: Finish,
79    {
80        let request::Body::Open(body) = self.body else {
81            return Err(self);
82        };
83        Ok(Self {
84            slot: self.slot,
85            body: request::Body::Finished(F::sync(body)),
86        })
87    }
88
89    fn each_open<'a, V: open::Each<F>>(&'a mut self, visit: V) -> V::Output<'a>
90    where
91        F: open::Set,
92    {
93        match &mut self.body {
94            request::Body::Open(body) => visit.apply(body),
95            request::Body::Finished(never) => match *never {},
96        }
97    }
98
99    fn fold_open<V: open::Fold<P, F>>(self, visit: V) -> V::Output
100    where
101        F: open::Set,
102    {
103        match self.body {
104            request::Body::Open(body) => visit.sync(self.slot, body),
105            request::Body::Finished(never) => match never {},
106        }
107    }
108
109    fn consume<O, V: FnOnce(F::Body) -> O>(self, visit: V) -> O
110    where
111        F: open::Set,
112    {
113        match self.body {
114            request::Body::Open(body) => visit(body),
115            request::Body::Finished(never) => match never {},
116        }
117    }
118}
119
120impl<P, F: Set> body::Flow<F> for Uniform<P, F> {
121    fn fold<T: body::Fold<F>>(self, fold: T) -> T::Output {
122        match self.body {
123            request::Body::Open(body) => fold.apply(body::Value::SyncOpen(body)),
124            request::Body::Finished(body) => fold.apply(body::Value::SyncFinished(body)),
125        }
126    }
127}
128
129impl<P, F, G> Admission<P, F, G> for Uniform<P, F>
130where
131    F: Set,
132    G: Set,
133{
134    type Output = Uniform<P, G>;
135
136    fn admit<V: admit::Visit<P, F, G>>(self, visit: &mut V) -> ControlFlow<V::Break, Self::Output> {
137        let (slot, body) = match self.body {
138            request::Body::Open(body) => {
139                let (slot, body) = visit.sync_open(self.slot, body)?;
140                (slot, request::Body::Open(body))
141            }
142            request::Body::Finished(body) => {
143                let (slot, body) = visit.sync_done(self.slot, body)?;
144                (slot, request::Body::Finished(body))
145            }
146        };
147        ControlFlow::Continue(Uniform { slot, body })
148    }
149}
150
151type AdmittedBody<P> = request::Body<
152    request::Admitted<exec::Sync, P, Track<Open>>,
153    request::Admitted<exec::Sync, P, Track<Finished>>,
154>;