Skip to main content

sark_http/h1/head/response/
mod.rs

1//! Response-head semantics and owner-free wire parts.
2
3mod admitted;
4mod coding;
5mod date;
6mod fields;
7mod parts;
8pub mod raw;
9mod server;
10
11pub use admitted::Admitted;
12pub use coding::Coding;
13pub use date::Date;
14pub use parts::Parts;
15pub use server::Server;
16
17use core::{convert::Infallible, marker::PhantomData};
18
19use o3::buffer::{
20    self,
21    resident::staging::{self, reserve},
22    write,
23};
24
25use crate::h1::head::{Limit, ParseError, field, response};
26use crate::payload::response::Method;
27
28/// Append-only input retaining the identity of one response parser.
29pub struct State<'id, S> {
30    source: S,
31    brand: PhantomData<*mut &'id ()>,
32}
33
34/// Progress tied to one input owner; failures consume it without replaying fields.
35pub struct Progress<'id> {
36    inner: response::raw::State,
37    brand: PhantomData<*mut &'id ()>,
38}
39
40impl<S> State<'_, S> {
41    pub fn with<R>(
42        source: S,
43        request: Method,
44        limit: Limit,
45        run: impl for<'id> FnOnce(State<'id, S>, Progress<'id>) -> R,
46    ) -> R {
47        let brand = PhantomData;
48        run(
49            State { source, brand },
50            Progress {
51                inner: response::raw::State::new(request, limit),
52                brand,
53            },
54        )
55    }
56
57    /// Releases the source, leaving no owner that can resume this parser.
58    pub fn into_inner(self) -> S {
59        self.source
60    }
61}
62
63impl<'id, S: buffer::raw::Source> State<'id, S> {
64    /// Borrows the retained source without permitting exclusive mutation.
65    pub fn source(&self) -> &S {
66        &self.source
67    }
68}
69
70impl<'id> Progress<'id> {
71    /// Parses appended bytes, retaining field and error borrows on their input owner.
72    pub fn advance<'owner, S: buffer::raw::Source, E>(
73        self,
74        source: &'owner State<'id, S>,
75        sink: impl FnMut(field::Entry<'owner>) -> Result<(), E>,
76    ) -> Result<(Self, Option<Parts>), ParseError<E>> {
77        // SAFETY: this invariant identity admits only its retained source; all source
78        // transitions preserve the exact prefix, and shared access prevents mutation.
79        let (inner, parts) = unsafe { self.inner.advance_from(source.as_ref(), sink) }?;
80        Ok((Self { inner, ..self }, parts))
81    }
82
83    /// Advances validation without emitting parsed field entries.
84    pub fn scan<S: buffer::raw::Source>(
85        self,
86        source: &State<'id, S>,
87    ) -> Result<(Self, Option<Parts>), ParseError<Infallible>> {
88        self.advance(source, |_| Ok(()))
89    }
90}
91
92impl<S: buffer::raw::Source> AsRef<[u8]> for State<'_, S> {
93    fn as_ref(&self) -> &[u8] {
94        self.source.as_ref()
95    }
96}
97
98impl<S: buffer::raw::Source + write::Sink> State<'_, S> {
99    pub fn try_extend(&mut self, bytes: &[u8]) -> Result<(), S::Error> {
100        self.source.write_slice(bytes)
101    }
102}
103
104impl<'d> State<'_, staging::Buf<'d>> {
105    pub fn try_reserve(&mut self, target: usize) -> Result<(), reserve::Error> {
106        self.source.try_reserve(target)
107    }
108
109    pub fn try_grow(&mut self) -> Result<(), reserve::Error> {
110        self.source.try_grow()
111    }
112}
113
114const _: () = {
115    assert!(core::mem::size_of::<State<'static, ()>>() == 0);
116    assert!(core::mem::size_of::<Progress<'static>>() <= 104);
117};