Skip to main content

sark_core/manifold/
stream.rs

1//! Static HTTP stream emission shared by protocol carriers.
2
3use core::{num::NonZero, ops::ControlFlow};
4
5use o3::buffer::segments;
6use sark_http::field;
7
8use crate::{life::session, manifold};
9
10/// Whether one semantic stream event owns the peer's end marker.
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
12#[repr(u8)]
13pub enum Boundary {
14    #[default]
15    More,
16    End,
17}
18
19const _: () = {
20    assert!(core::mem::size_of::<Boundary>() == core::mem::size_of::<bool>());
21    assert!(core::mem::align_of::<Boundary>() == core::mem::align_of::<bool>());
22};
23
24/// Position of one field section in an HTTP message.
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26#[repr(u8)]
27pub enum Section {
28    Initial,
29    Trailing,
30}
31
32const _: () = {
33    assert!(core::mem::size_of::<Section>() == core::mem::size_of::<bool>());
34    assert!(core::mem::align_of::<Section>() == core::mem::align_of::<bool>());
35};
36
37/// Carrier-packed stream identity and end marker.
38pub trait Message: Copy {
39    type Key: manifold::raw::Key;
40
41    fn key(self) -> Self::Key;
42
43    fn boundary(self) -> Boundary;
44}
45
46/// Affine retained DATA ownership supplied by one carrier.
47pub trait Payload<C: session::Storage>: Sized {
48    /// Admission owner released by `Drop` when its DATA bytes leave framing.
49    type Permit;
50
51    fn into_parts(self) -> (segments::Chain<C>, Self::Permit);
52}
53
54/// Result of emitting one complete head or trailer field section.
55#[derive(Clone, Copy, PartialEq, Eq)]
56pub enum Control<B> {
57    Written,
58    /// Encoded once and retained by the carrier; retry with `Write::commit`.
59    Prepared(B),
60    /// Not admitted; a later call must provide the source again.
61    Blocked(B),
62}
63
64/// Result of emitting a non-empty body prefix.
65#[derive(Clone, Copy, PartialEq, Eq)]
66pub enum Data<B> {
67    Written(NonZero<usize>),
68    Blocked(B),
69}
70
71/// Static write access to one native HTTP stream.
72pub trait Write<P> {
73    type Block;
74    type Error;
75
76    fn headers<S: field::Source>(
77        &mut self,
78        source: S,
79        boundary: Boundary,
80    ) -> Result<Control<Self::Block>, Self::Error>;
81
82    fn data(
83        &mut self,
84        prefix: &[u8],
85        payload: &P,
86        offset: usize,
87        boundary: Boundary,
88    ) -> Result<Data<Self::Block>, Self::Error>;
89
90    /// Retries only this stream's retained field section, without evaluating a source.
91    fn commit(&mut self) -> Result<ControlFlow<Self::Block>, Self::Error>;
92
93    /// Discards only this stream's retained field section.
94    fn discard(&mut self);
95}