Skip to main content

sark_core/manifold/
mod.rs

1use core::mem;
2
3use o3::buffer::{resident, segments};
4use sark_http::{payload, payload::response::dispatch};
5
6use crate::{request, route};
7
8pub mod client;
9pub mod raw;
10pub mod schedule;
11pub mod server;
12pub mod stream;
13pub mod task;
14
15/// Final-link HTTP/1 payload retaining its physical owners and transport tag.
16#[doc(hidden)]
17pub enum Body<'d, K: 'd = ()> {
18    Shared {
19        owner: resident::Shared<'d>,
20        tag: K,
21    },
22    Segments {
23        owners: segments::Many<resident::Shared<'d>>,
24        tag: K,
25    },
26    Frozen {
27        owner: payload::compress::Frozen,
28        tag: K,
29    },
30}
31
32impl<'d, K> Body<'d, K> {
33    /// Lowers admitted owners without copying bytes or segment metadata.
34    #[doc(hidden)]
35    pub fn duplex(chunk: segments::Nonempty<resident::Shared<'d>>, tag: K) -> Self {
36        match chunk {
37            segments::Nonempty::One(owner) => Self::Shared {
38                owner: owner.into_inner(),
39                tag,
40            },
41            segments::Nonempty::Many(owners) => Self::Segments { owners, tag },
42        }
43    }
44
45    /// Returns every physical owner from a publication rejected before the
46    /// final link accepted it.
47    #[doc(hidden)]
48    pub fn release(self) -> K {
49        match self {
50            Self::Shared { tag, .. } | Self::Segments { tag, .. } | Self::Frozen { tag, .. } => tag,
51        }
52    }
53}
54
55pub struct EmptyState;
56
57impl EmptyState {
58    pub const REF: &'static Self = &Self;
59}
60
61pub trait Response<'req, 'd>: Sized {
62    type Kind;
63    type Output: dispatch::Emit<'req, 'd>;
64    type Stream;
65
66    const BODY_KIND: payload::Kind = <Self::Output as dispatch::Emit<'req, 'd>>::BODY;
67}
68
69impl<'req, 'd, R> Response<'req, 'd> for R
70where
71    R: dispatch::IntoOutput<'req, 'd>,
72{
73    type Kind = <R::Output as dispatch::Emit<'req, 'd>>::Kind;
74    type Output = R::Output;
75    type Stream = <R::Output as dispatch::Emit<'req, 'd>>::Stream;
76}
77
78/// Projected request parts and the independently borrowed application state.
79pub type Args<'view, 'req, 'd, 'state, R, State> = (
80    <R as route::Project>::Params<'req>,
81    &'view request::View<'req, 'd, <R as route::Schema>::Frame>,
82    <R as route::Project>::Headers<'req>,
83    <R as route::Project>::ParsedBody<'req, 'd>,
84    &'state State,
85);
86
87pub trait Route<State>: route::Spec<Kind: dispatch::Dispatch> {
88    type Response<'req, 'd>: dispatch::Emit<'req, 'd, Kind = Self::Kind, Stream = Self::Stream<'d>>
89    where
90        'd: 'req;
91
92    fn invoke<'req, 'd, 'state>(
93        input: Args<'_, 'req, 'd, 'state, Self::Request, State>,
94    ) -> Self::Response<'req, 'd>
95    where
96        'req: 'state,
97        'd: 'req;
98}
99
100const _: [(); 0] = [(); mem::size_of::<EmptyState>()];