sark_http/h1/codec/decode/request/
head.rs1use core::convert::Infallible;
2use std::num::NonZero;
3
4use crate::h1::{
5 codec::decode::fields,
6 field, framing,
7 head::{Limit, ParseError, line, request},
8};
9
10pub struct Head<'input, F> {
12 pub method: &'input [u8],
13 pub target: &'input [u8],
14 pub version: u8,
15 pub admission: framing::Admission,
16 pub connection: field::Connection,
17 pub fields: F,
18 pub header_len: NonZero<u32>,
19}
20
21impl<'input> Head<'input, ()> {
22 pub fn scan(input: &'input [u8], bound: usize) -> Result<Option<Self>, ParseError<Infallible>> {
23 let Some(plan) = request::Parts::scan(input, Limit::DEFAULT.with_bytes(bound))? else {
24 return Ok(None);
25 };
26 Ok(Some(Self::from(plan, ())))
27 }
28}
29
30impl<'input, F: fields::Sink<'input>> Head<'input, F> {
31 pub fn parse(
32 input: &'input [u8],
33 bound: usize,
34 mut fields: F,
35 ) -> Result<Option<Self>, ParseError<F::Error>> {
36 let Some(plan) = request::Parts::parse(input, Limit::DEFAULT.with_bytes(bound), |field| {
37 fields.entry(field)
38 })?
39 else {
40 return Ok(None);
41 };
42 Ok(Some(Self::from(plan, fields)))
43 }
44}
45
46impl<'input, F> Head<'input, F> {
47 fn from(plan: request::Parts<&'input [u8]>, fields: F) -> Self {
48 let (method, target) = plan.line();
49 let version = match plan.version() {
50 line::Version::Ten => 0,
51 line::Version::Eleven => 1,
52 };
53 Self {
54 method,
55 target,
56 version,
57 admission: plan.admission(),
58 connection: plan.connection(),
59 fields,
60 header_len: plan.wire_len(),
61 }
62 }
63}