1use std::ops;
2
3use o3::buffer::{bytes::scope, pool, pool::owners, storage};
4use sark_http::{
5 field::metadata::section::storage::Bytes,
6 payload::owned,
7 request,
8 request::{Id, Layout, Source},
9};
10
11use crate::{
12 body,
13 request::{BindError, Head, Parts, Retained, frame::proof},
14 route,
15};
16
17pub trait Bind: request::raw::Bind {
18 unsafe fn try_head<P: proof::Proof>(
22 self,
23 path: Option<ops::Range<usize>>,
24 path_len: Option<usize>,
25 pseudo: Option<ops::Range<usize>>,
26 host: Option<ops::Range<usize>>,
27 ) -> Result<Head<Self::Owner, P>, BindError> {
28 let bound = unsafe { request::raw::Bind::try_bind(self, path, path_len, pseudo, host) }
30 .map_err(BindError::Layout)?;
31 Head::try_bound(bound)
32 }
33}
34
35impl<H: request::raw::Bind> Bind for H {}
36
37pub struct Parsed<H, R: route::Schema> {
39 owner: H,
40 params: R::RawParams,
41 headers: R::RawHeaders,
42}
43
44impl<O: Source, F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Head<O, F>, R> {
45 pub unsafe fn try_bind(
49 owner: O,
50 layout: Layout,
51 params: R::RawParams,
52 headers: R::RawHeaders,
53 ) -> Result<Self, BindError> {
54 let owner = unsafe { Head::try_parts(owner, layout) }?;
56 Ok(unsafe { Self::new(owner, params, headers) })
58 }
59
60 pub const unsafe fn new(
63 owner: Head<O, F>,
64 params: R::RawParams,
65 headers: R::RawHeaders,
66 ) -> Self {
67 Self {
68 owner,
69 params,
70 headers,
71 }
72 }
73
74 pub fn borrow(&self) -> Parsed<Head<&[u8], F>, R> {
75 Parsed {
76 owner: self.owner.borrow(),
77 params: self.params,
78 headers: self.headers,
79 }
80 }
81}
82
83impl<H, R: route::Schema> Parsed<H, R> {
84 pub const fn owner(&self) -> &H {
85 &self.owner
86 }
87
88 pub fn into_owner(self) -> H {
89 self.owner
90 }
91
92 pub const fn params(&self) -> &R::RawParams {
93 &self.params
94 }
95
96 pub const fn headers(&self) -> &R::RawHeaders {
97 &self.headers
98 }
99}
100
101impl<F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Head<Bytes, F>, R> {
102 pub fn retain(self) -> Parsed<Head<storage::Shared, F>, R> {
103 Parsed {
104 owner: self.owner.retain(),
105 params: self.params,
106 headers: self.headers,
107 }
108 }
109}
110
111impl<F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Head<storage::Shared, F>, R> {
112 pub fn with_id<'d>(self, id: Id<'d>) -> Parsed<Parts<'d, F>, R> {
113 Parsed {
114 owner: Parts::from_head(id, self.owner),
115 params: self.params,
116 headers: self.headers,
117 }
118 }
119}
120
121impl<'d, F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Parts<'d, F>, R> {
122 pub fn with_body(self, body: body::Body<owned::Segments<'d>>) -> Parsed<Retained<'d, F>, R> {
123 Parsed {
124 owner: Retained {
125 parts: self.owner,
126 body,
127 },
128 params: self.params,
129 headers: self.headers,
130 }
131 }
132}
133
134impl<'d, F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Retained<'d, F>, R> {
135 pub fn into_parts(self) -> (Parsed<Parts<'d, F>, R>, body::Body<owned::Segments<'d>>) {
136 let (parts, body) = self.owner.into_parts();
137 (
138 Parsed {
139 owner: parts,
140 params: self.params,
141 headers: self.headers,
142 },
143 body,
144 )
145 }
146}
147
148impl<F: proof::Proof, R: route::Schema<Frame = F>> Parsed<Head<Bytes, F>, R> {
149 pub fn scope<T>(
150 self,
151 use_head: impl for<'id> FnOnce(
152 Parsed<
153 Head<
154 Bytes<
155 scope::Owner<
156 'id,
157 pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>,
158 >,
159 >,
160 F,
161 >,
162 R,
163 >,
164 ) -> T,
165 ) -> T {
166 let Self {
167 owner,
168 params,
169 headers,
170 } = self;
171 owner.scope(|owner| {
172 use_head(Parsed {
173 owner,
174 params,
175 headers,
176 })
177 })
178 }
179}
180
181impl<F: proof::Proof, R: route::Schema<Frame = F>>
182 Parsed<
183 Head<
184 Bytes<
185 scope::Owner<
186 '_,
187 pool::Span<owners::Plain<pool::Layout>, pool::Owned, pool::Frozen>,
188 >,
189 >,
190 F,
191 >,
192 R,
193 >
194{
195 pub fn into_inner(self) -> Parsed<Head<Bytes, F>, R> {
196 Parsed {
197 owner: self.owner.into_inner(),
198 params: self.params,
199 headers: self.headers,
200 }
201 }
202}