1use core::{convert::Infallible, marker::PhantomData};
2
3use o3::mem::Rejected;
4use request::body::Source;
5use sark_http::{method::Method, owner::handoff::input, payload::owned, request};
6
7use crate::{
8 body,
9 decode::{Decode, Scoped, exec, state},
10 manifold::stream::Boundary,
11};
12
13pub mod admit;
14mod project;
15
16pub use project::Project;
17
18#[repr(C)]
20pub struct Admitted<K, P, B> {
21 prepared: P,
22 body: B,
23 kind: PhantomData<fn() -> K>,
24}
25
26impl<K, P, B> Admitted<K, P, B> {
27 pub(in crate::decode) const fn new(prepared: P, body: B) -> Self {
28 Self {
29 prepared,
30 body,
31 kind: PhantomData,
32 }
33 }
34
35 pub const fn body(&self) -> &B {
36 &self.body
37 }
38
39 pub const fn body_mut(&mut self) -> &mut B {
40 &mut self.body
41 }
42
43 pub fn into_body(self) -> B {
44 self.body
45 }
46
47 pub fn into_parts(self) -> (P, B) {
48 (self.prepared, self.body)
49 }
50
51 pub fn try_map_body<T, E>(
52 self,
53 f: impl FnOnce(B) -> Result<T, E>,
54 ) -> Result<Admitted<K, P, T>, Failure<K, P, E>> {
55 match f(self.body) {
56 Ok(body) => Ok(Admitted::new(self.prepared, body)),
57 Err(error) => Err(Failure::new(error, self.prepared)),
58 }
59 }
60}
61
62impl<P, B> Admitted<exec::Duplex, P, B> {
63 pub fn build<T, E>(self, f: impl FnOnce(P) -> Result<T, E>) -> Result<(T, B), (E, B)> {
64 match f(self.prepared) {
65 Ok(value) => Ok((value, self.body)),
66 Err(error) => Err((error, self.body)),
67 }
68 }
69}
70
71impl<K, P, S> Admitted<K, P, body::Body<S>> {
72 pub fn ready(self) -> Ready<K, P, S> {
73 Ready::new(self.prepared, self.body)
74 }
75}
76
77#[must_use]
79#[repr(C)]
80#[derive(Debug)]
81pub struct Ready<K, P, S> {
82 prepared: P,
83 body: body::Body<S>,
84 kind: PhantomData<fn() -> K>,
85}
86
87impl<K, P, S> Ready<K, P, S> {
88 pub(in crate::decode) const fn new(prepared: P, body: body::Body<S>) -> Self {
89 Self {
90 prepared,
91 body,
92 kind: PhantomData,
93 }
94 }
95
96 pub const fn body(&self) -> &body::Body<S> {
97 &self.body
98 }
99
100 pub const fn prepared(&self) -> &P {
101 &self.prepared
102 }
103
104 pub fn into_body(self) -> body::Body<S> {
105 self.body
106 }
107}
108
109impl<P, S> Ready<exec::Task, P, S> {
110 pub fn into_parts(self) -> (P, body::Body<S>) {
111 (self.prepared, self.body)
112 }
113}
114
115impl<P, S> Ready<exec::Sync, P, S> {
116 pub fn try_project<'d, D, T, F>(
119 self,
120 decoder: &D,
121 f: F,
122 ) -> Result<(T, body::Body<S>), Project<exec::Sync, P, S>>
123 where
124 S: Source<'d>,
125 D: Decode<Prepared = P>,
126 F: for<'a> FnOnce(&D, Scoped<'a, 'd, D>) -> T,
127 {
128 let Self {
129 prepared, mut body, ..
130 } = self;
131 let output = match decoder.try_project(prepared, body.input(), |view| f(decoder, view)) {
132 Ok((output, ())) => output,
133 Err(failure) => {
134 let ((prepared, _), error) = failure.into_parts();
135 return Err(Project::new(error, Ready::new(prepared, body)));
136 }
137 };
138 Ok((output, body))
139 }
140}
141
142impl<'d, P> Ready<exec::Sync, P, owned::Segments<'d>> {
143 pub fn with_input<T>(
145 self,
146 run: impl for<'owner> FnOnce(P, body::Input<input::Input<'owner, 'd>>) -> T,
147 ) -> T {
148 let Self { prepared, body, .. } = self;
149 let (source, len) = body.into_parts();
150 input::Input::with(source, |source| run(prepared, body::Input { source, len }))
151 }
152}
153
154#[must_use]
156#[derive(Debug)]
157pub struct Failure<K, P, E> {
158 error: E,
159 prepared: P,
160 kind: PhantomData<fn() -> K>,
161}
162
163impl<K, P, E> Failure<K, P, E> {
164 const fn new(error: E, prepared: P) -> Self {
165 Self {
166 error,
167 prepared,
168 kind: PhantomData,
169 }
170 }
171
172 pub const fn error(&self) -> &E {
173 &self.error
174 }
175
176 pub fn discard(self) -> E {
178 self.error
179 }
180
181 pub fn into_parts(self) -> (E, P) {
182 (self.error, self.prepared)
183 }
184}
185
186pub enum Body<O, F = O> {
187 Open(O),
188 Finished(F),
189}
190
191#[must_use]
193pub struct Plain<T>(T);
194
195impl<T> Plain<T> {
196 #[doc(hidden)]
197 pub const fn new(state: T) -> Self {
198 Self(state)
199 }
200
201 pub fn into_state(self) -> T {
202 self.0
203 }
204}
205
206#[must_use]
208pub struct Guarded<T> {
209 state: T,
210 method: Method,
211}
212
213impl<T> Guarded<T> {
214 #[doc(hidden)]
215 pub const fn new(state: T, method: Method) -> Self {
216 Self { state, method }
217 }
218
219 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Guarded<U> {
220 Guarded::new(f(self.state), self.method)
221 }
222
223 pub fn fold<U>(self, f: impl FnOnce(T) -> U) -> U {
224 f(self.state)
225 }
226
227 pub fn state_mut(&mut self) -> &mut T {
228 &mut self.state
229 }
230
231 pub fn into_parts(self) -> (T, Method) {
232 (self.state, self.method)
233 }
234}
235
236#[must_use]
239pub enum Start<U, G> {
240 Plain(Plain<U>),
241 Guarded(Guarded<G>),
242}
243
244impl<U, G> Start<U, G> {
245 #[doc(hidden)]
246 pub const fn plain(state: U) -> Self {
247 Self::Plain(Plain::new(state))
248 }
249
250 #[doc(hidden)]
251 pub const fn guarded(state: G, method: Method) -> Self {
252 Self::Guarded(Guarded::new(state, method))
253 }
254}
255
256pub trait Selection<P> {
258 type Guard: state::Family<P>;
259 type Routed: state::Flow<P, state::Routed, Family = Self::Guard>;
260 type Deferred<T>;
261}
262
263impl<P, U> Selection<P> for Plain<U>
264where
265 U: state::Flow<P, state::Routed>,
266{
267 type Guard = U::Family;
268 type Routed = U;
269 type Deferred<T> = Infallible;
270}
271
272impl<P, G> Selection<P> for Guarded<G>
273where
274 G: state::Flow<P, state::Routed>,
275{
276 type Guard = G::Family;
277 type Routed = G;
278 type Deferred<T> = T;
279}
280
281impl<P, U, G> Selection<P> for Start<U, G>
282where
283 G: state::Flow<P, state::Routed>,
284{
285 type Guard = G::Family;
286 type Routed = G;
287 type Deferred<T> = T;
288}
289
290pub trait Head: Sized {
292 type Prepared: Prepared;
293 type Start: Selection<Self::Prepared>;
294
295 fn try_start(
296 self,
297 limit: usize,
298 boundary: Boundary,
299 ) -> Result<Self::Start, Rejected<Self, body::Error>>;
300}
301
302pub trait Prepared: Sized {
304 type Execution: exec::Set;
305 type Family: state::Family<Self>;
306}
307
308pub trait Synchronous:
310 Prepared<Execution = exec::Sync, Family: state::Homogeneous<Self, exec::Sync>>
311{
312}
313
314impl<P> Synchronous for P
315where
316 P: Prepared<Execution = exec::Sync>,
317 P::Family: state::Homogeneous<P, exec::Sync>,
318{
319}
320
321const _: () = {
322 type Body = body::Body<()>;
323 type ReadyProof = Ready<exec::Sync, (), ()>;
324 assert!(core::mem::size_of::<ReadyProof>() == core::mem::size_of::<Body>());
325 assert!(core::mem::align_of::<ReadyProof>() == core::mem::align_of::<Body>());
326 assert!(
327 core::mem::size_of::<Admitted<exec::Task, usize, usize>>()
328 == 2 * core::mem::size_of::<usize>()
329 );
330};