sark_http/h1/field/
value.rs1use crate::field::{self, scan};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub enum Error {
5 Empty,
6 InvalidByte,
7 Overflow,
8 InvalidOrdering,
9}
10
11#[derive(Clone, Copy, PartialEq, Eq)]
12pub(super) enum Match {
13 Taken,
14 Other,
15}
16
17pub(super) struct Parser<'a> {
18 value: &'a [u8],
19}
20
21impl<'a> Parser<'a> {
22 pub(super) const fn new(value: &'a [u8]) -> Self {
23 Self { value }
24 }
25
26 pub(super) fn skip_ows(&mut self) {
27 while let Some((b' ' | b'\t', tail)) = self.value.split_first() {
28 self.value = tail;
29 }
30 }
31
32 pub(super) fn is_done(&self) -> bool {
33 self.value.is_empty()
34 }
35
36 pub(super) fn take(&mut self, byte: u8) -> Match {
37 let Some((&first, tail)) = self.value.split_first() else {
38 return Match::Other;
39 };
40 if first != byte {
41 return Match::Other;
42 }
43 self.value = tail;
44 Match::Taken
45 }
46
47 pub(super) fn token(&mut self) -> Result<&'a [u8], Error> {
48 let (token, tail) =
49 match scan::Match::find_by(self.value, |byte| !field::Error::is_name_byte(byte)) {
50 Some(end) => (end.prefix(), end.tail()),
51 None => (self.value, &self.value[self.value.len()..]),
52 };
53 if token.is_empty() {
54 return Err(if self.is_done() {
55 Error::Empty
56 } else {
57 Error::InvalidByte
58 });
59 }
60 self.value = tail;
61 Ok(token)
62 }
63
64 pub(super) fn item(&mut self) -> Result<(), Error> {
65 let Some((b'"', tail)) = self.value.split_first() else {
66 self.token()?;
67 return Ok(());
68 };
69 let mut bytes = tail.iter();
70 while let Some(&byte) = bytes.next() {
71 match byte {
72 b'"' => {
73 self.value = bytes.as_slice();
74 return Ok(());
75 }
76 b'\\' => {
77 let escaped = bytes.next().ok_or(Error::InvalidByte)?;
78 if !matches!(escaped, b'\t' | b' ' | 0x21..=0x7e | 0x80..=0xff) {
79 return Err(Error::InvalidByte);
80 }
81 }
82 b'\t' | b' ' | b'!' | 0x23..=0x5b | 0x5d..=0x7e | 0x80..=0xff => {}
83 0..=8 | 10..=31 | 0x7f => return Err(Error::InvalidByte),
84 }
85 }
86 Err(Error::InvalidByte)
87 }
88}