Skip to main content

sark_http/h1/head/request/pool/
meta.rs

1use std::{ops, str};
2
3use o3::buffer::{
4    pool,
5    pool::{owners, state},
6};
7
8use crate::h1::{
9    head::request::{offers, pool::Layout},
10    switch,
11};
12
13/// Request-head authority retained for exactly one upstream response lifetime.
14pub struct Meta<'d> {
15    pub(in crate::h1::head::request) bytes:
16        pool::Span<owners::Plain<pool::Layout>, pool::Borrowed<'d>, state::Uninit>,
17}
18
19impl<'d> Meta<'d> {
20    pub fn method(&self) -> &str {
21        let layout = self.layout();
22        self.text(0..layout.method_end())
23    }
24
25    pub fn target(&self) -> &str {
26        let layout = self.layout();
27        self.text(layout.target_start()..layout.target_end())
28    }
29
30    pub fn transition(&self) -> switch::Intent {
31        self.layout().transition()
32    }
33
34    pub fn select(
35        &self,
36        selected: &[u8],
37    ) -> Result<Option<switch::Selection>, switch::UpgradeError> {
38        offers::View::from_meta(self)
39            .map(|view| switch::Selection::from_offers(view, selected))
40            .transpose()
41    }
42
43    pub(in crate::h1::head::request) fn layout(&self) -> Layout {
44        // SAFETY: both private constructors write a complete native-endian
45        // Layout prefix, and Meta never exposes mutable storage.
46        unsafe {
47            self.bytes
48                .as_slice()
49                .as_ptr()
50                .cast::<Layout>()
51                .read_unaligned()
52        }
53    }
54
55    pub(in crate::h1::head::request) fn data(&self) -> &[u8] {
56        // SAFETY: every Meta owns its initialized Layout prefix.
57        unsafe { self.bytes.as_slice().get_unchecked(Layout::BYTES..) }
58    }
59
60    fn text(&self, range: ops::Range<usize>) -> &str {
61        // SAFETY: both private constructors retain the native parser's UTF-8
62        // proof in this immutable owner with offsets bounded by its lease.
63        unsafe { str::from_utf8_unchecked(self.data().get_unchecked(range)) }
64    }
65}
66
67const _: () = assert!(size_of::<Meta<'static>>() == 2 * size_of::<usize>());