sark_http/h1/field/
expect.rs1use crate::{field, h1::framing};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub enum Error {
5 Unsupported,
6}
7
8#[repr(u8)]
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11pub enum Decision {
12 #[default]
13 None,
14 Continue,
15}
16
17impl Decision {
18 pub const fn is_continue(self) -> bool {
19 matches!(self, Self::Continue)
20 }
21}
22
23#[repr(transparent)]
25#[derive(Clone, Copy, Default, PartialEq, Eq)]
26pub struct State(u8);
27
28impl State {
29 const CONTINUE: u8 = 1 << 0;
30 const UNSUPPORTED: u8 = 1 << 1;
31
32 pub fn push(mut self, value: &[u8]) -> Self {
33 for raw in value.split(|byte| *byte == b',') {
34 let token = field::Error::trim_ows(raw);
35 if token.is_empty() {
36 continue;
37 }
38 if token.eq_ignore_ascii_case(b"100-continue") {
39 self.0 |= Self::CONTINUE;
40 } else {
41 self.0 |= Self::UNSUPPORTED;
42 }
43 }
44 self
45 }
46
47 pub const fn finish(self, body: framing::RequestBody) -> Result<Decision, Error> {
48 if self.0 & Self::UNSUPPORTED != 0 {
49 return Err(Error::Unsupported);
50 }
51 Ok(
52 if self.0 & Self::CONTINUE != 0 && !matches!(body, framing::RequestBody::Empty) {
53 Decision::Continue
54 } else {
55 Decision::None
56 },
57 )
58 }
59}
60
61const _: () = assert!(core::mem::size_of::<Decision>() == 1);
62const _: () = assert!(core::mem::size_of::<State>() == 1);