1#[doc(hidden)]
2pub mod base64;
3pub mod date;
4pub mod head;
5pub mod metadata;
6pub mod raw;
7pub mod scan;
8pub mod storage;
9pub mod text;
10
11use std::{convert::Infallible, iter::Copied, slice};
12
13pub use storage::{Lower, Name, Value};
14
15#[macro_export]
18macro_rules! field_literal {
19 ($value:expr $(,)?) => {
20 const {
21 match $value {
22 ::core::result::Result::Ok(value) => value,
23 ::core::result::Result::Err(_) => ::core::panic!("literal"),
24 }
25 }
26 };
27}
28
29use metadata::map::record;
30use storage::encoded;
31
32pub use crate::field_literal as literal;
33use crate::payload::response::status;
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
36pub enum Error {
37 Empty,
38 InvalidByte { index: usize, byte: u8 },
39}
40
41#[repr(u8)]
43#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
44pub enum Indexing {
45 #[default]
46 Allowed,
47 Never,
48}
49
50impl Indexing {
51 pub(in crate::field) const fn from_byte(value: u8) -> Option<Self> {
52 match value {
53 0 => Some(Self::Allowed),
54 1 => Some(Self::Never),
55 _ => None,
56 }
57 }
58
59 pub(in crate::field) const fn from_never(never: bool) -> Self {
60 if never { Self::Never } else { Self::Allowed }
61 }
62}
63
64pub trait Writer {
66 fn write_byte(&mut self, byte: u8);
67
68 fn write_slice(&mut self, bytes: &[u8]);
69}
70
71pub trait Encode: encoded::Encoded {
73 fn encoded_len(&self) -> usize;
74
75 fn try_write<E>(self, emit: impl FnMut(&[u8]) -> Result<(), E>) -> Result<(), E>;
77
78 fn encode(self, out: &mut impl Writer)
79 where
80 Self: Sized,
81 {
82 match self.try_write(|bytes| {
83 out.write_slice(bytes);
84 Ok::<_, Infallible>(())
85 }) {
86 Ok(()) => {}
87 Err(never) => match never {},
88 }
89 }
90}
91
92pub trait Sink<'field> {
94 fn entry(&mut self, field: Entry<'field>);
95
96 fn group(&mut self, group: &Group<'field>) {
98 for entry in group.entries() {
99 self.entry(*entry);
100 }
101 }
102
103 fn field(&mut self, name: Lower<&'field [u8]>, value: Value<&'field [u8]>) {
104 self.entry(Entry::new(name, value));
105 }
106
107 fn encoded_with<E: Encode>(&mut self, name: Lower<&'field [u8]>, value: E, indexing: Indexing);
108
109 fn generated<E: Encode>(&mut self, name: Lower<&'field [u8]>, value: E) {
111 self.encoded_with(name, value, Indexing::Allowed);
112 }
113}
114
115pub trait Source {
117 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>);
118}
119
120pub trait AsValue {
122 fn as_value(&self) -> Value<&[u8]>;
123}
124
125impl<T: storage::Bytes> AsValue for Value<T> {
126 fn as_value(&self) -> Value<&[u8]> {
127 Value(self.0.as_bytes())
128 }
129}
130
131impl<T: storage::Bytes> Encode for Value<T> {
132 fn encoded_len(&self) -> usize {
133 self.as_bytes().len()
134 }
135
136 fn try_write<E>(self, mut emit: impl FnMut(&[u8]) -> Result<(), E>) -> Result<(), E> {
137 let Self(owner) = self;
138 emit(owner.as_bytes())
139 }
140}
141
142impl<W: Writer + ?Sized> Writer for &mut W {
143 fn write_byte(&mut self, byte: u8) {
144 (**self).write_byte(byte);
145 }
146
147 fn write_slice(&mut self, bytes: &[u8]) {
148 (**self).write_slice(bytes);
149 }
150}
151
152impl<S: Source + ?Sized> Source for &S {
153 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
154 (**self).emit(sink);
155 }
156}
157
158impl Source for [Entry<'_>] {
159 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
160 for field in self {
161 sink.entry(*field);
162 }
163 }
164}
165
166impl<const N: usize> Source for [Entry<'_>; N] {
167 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
168 self.as_slice().emit(sink);
169 }
170}
171
172impl Source for Vec<Entry<'_>> {
173 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
174 self.as_slice().emit(sink);
175 }
176}
177
178impl<'entry, 'value> Source for Copied<slice::Iter<'entry, Entry<'value>>>
179where
180 'value: 'entry,
181{
182 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
183 for field in self.clone() {
184 sink.entry(field);
185 }
186 }
187}
188
189impl<'entry, 'value> Source for slice::Iter<'entry, Entry<'value>>
190where
191 'value: 'entry,
192{
193 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
194 for field in self.clone() {
195 sink.entry(*field);
196 }
197 }
198}
199
200impl Error {
201 pub fn trim_ows(mut value: &[u8]) -> &[u8] {
202 while matches!(value.first(), Some(b' ' | b'\t')) {
203 value = &value[1..];
204 }
205 while matches!(value.last(), Some(b' ' | b'\t')) {
206 value = &value[..value.len() - 1];
207 }
208 value
209 }
210
211 pub const fn name(name: &[u8]) -> Result<(), Self> {
212 if name.is_empty() {
213 return Err(Self::Empty);
214 }
215 let mut index = 0;
216 while index < name.len() {
217 let byte = name[index];
218 if !Self::is_name_byte(byte) {
219 return Err(Self::InvalidByte { index, byte });
220 }
221 index += 1;
222 }
223 Ok(())
224 }
225
226 pub const fn is_name_byte(byte: u8) -> bool {
227 byte.is_ascii_alphanumeric()
228 | (byte == b'!')
229 | (byte.wrapping_sub(b'#') <= b'\'' - b'#')
230 | (byte.wrapping_sub(b'*') <= b'+' - b'*')
231 | (byte.wrapping_sub(b'-') <= b'.' - b'-')
232 | (byte.wrapping_sub(b'^') <= b'`' - b'^')
233 | (byte == b'|')
234 | (byte == b'~')
235 }
236
237 pub const fn value(value: &[u8]) -> Result<(), Self> {
238 let mut index = 0;
239 while index < value.len() {
240 let byte = value[index];
241 if !Self::is_text(byte) {
242 return Err(Self::InvalidByte { index, byte });
243 }
244 index += 1;
245 }
246 Ok(())
247 }
248
249 pub const fn is_text(byte: u8) -> bool {
250 ((byte >= 0x20) & (byte != 0x7f)) | (byte == b'\t')
251 }
252}
253
254pub struct Response<F> {
256 value: Value<[u8; 3]>,
257 fields: F,
258}
259
260impl<F> Response<F> {
261 pub const fn new(status: status::Code, fields: F) -> Self {
262 Self {
263 value: Value(status.as_bytes()),
264 fields,
265 }
266 }
267}
268
269impl<F: Source> Source for Response<F> {
270 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
271 sink.entry(Entry::pseudo(Pseudo::Status, self.value.borrow()));
272 self.fields.emit(sink);
273 }
274}
275
276#[derive(Clone, Copy, Debug, PartialEq, Eq)]
278#[repr(transparent)]
279pub struct Entry<'a>(pub(in crate::field) record::Entry<'a>);
280
281#[derive(Clone, Copy, Debug, PartialEq, Eq)]
283pub enum Pseudo {
284 Method,
285 Scheme,
286 Authority,
287 Path,
288 Protocol,
289 Status,
290}
291
292impl<'a> Entry<'a> {
293 pub const fn new(name: Lower<&'a [u8]>, value: Value<&'a [u8]>) -> Self {
294 Self(record::Entry::new(name.0, value.0))
295 }
296
297 pub const fn pseudo(name: Pseudo, value: Value<&'a [u8]>) -> Self {
298 let name = match name {
299 Pseudo::Method => b":method".as_slice(),
300 Pseudo::Scheme => b":scheme".as_slice(),
301 Pseudo::Authority => b":authority".as_slice(),
302 Pseudo::Path => b":path".as_slice(),
303 Pseudo::Protocol => b":protocol".as_slice(),
304 Pseudo::Status => b":status".as_slice(),
305 };
306 Self(record::Entry::new(name, value.0))
307 }
308
309 pub const fn with_index(self, indexing: Indexing) -> Self {
310 Self(self.0.with_index(indexing))
311 }
312
313 pub const fn name(self) -> &'a [u8] {
314 self.0.name
315 }
316
317 pub const fn value(self) -> Value<&'a [u8]> {
318 Value(self.0.value)
319 }
320
321 pub const fn indexing(self) -> Indexing {
322 self.0.indexing
323 }
324
325 pub const fn as_record(&self) -> record::Entry<'a> {
326 self.0
327 }
328}
329
330#[derive(Clone, Copy, Debug, PartialEq, Eq)]
332pub struct Group<'a> {
333 entries: &'a [Entry<'a>],
334 wire: &'a [u8],
335}
336
337#[derive(Clone, Copy, Debug, PartialEq, Eq)]
339pub struct Mismatch {
340 pub offset: usize,
341 pub expected: Option<u8>,
342 pub actual: Option<u8>,
343}
344
345struct Cursor<'a> {
346 wire: &'a [u8],
347 offset: usize,
348}
349
350impl<'a> Group<'a> {
351 pub const fn try_new(entries: &'a [Entry<'a>], wire: &'a [u8]) -> Result<Self, Mismatch> {
352 let mut cursor = Cursor { wire, offset: 0 };
353 let mut index = 0;
354 while index < entries.len() {
355 let entry = entries[index];
356 let parts = [entry.name(), b": ", entry.value().get(), b"\r\n"];
357 let mut part = 0;
358 while part < parts.len() {
359 if let Err(error) = cursor.check(parts[part]) {
360 return Err(error);
361 }
362 part += 1;
363 }
364 index += 1;
365 }
366 if let Some((&actual, _)) = cursor.wire.split_first() {
367 return Err(Mismatch {
368 offset: cursor.offset,
369 expected: None,
370 actual: Some(actual),
371 });
372 }
373 Ok(Self { entries, wire })
374 }
375
376 pub const fn entries(&self) -> &'a [Entry<'a>] {
377 self.entries
378 }
379
380 pub const fn wire(&self) -> &'a [u8] {
381 self.wire
382 }
383}
384
385impl Source for Group<'_> {
386 fn emit<'field>(&'field self, sink: &mut impl Sink<'field>) {
387 sink.group(self);
388 }
389}
390
391impl Cursor<'_> {
392 const fn check(&mut self, expected: &[u8]) -> Result<(), Mismatch> {
393 let mut index = 0;
394 while index < expected.len() {
395 let byte = expected[index];
396 let (actual, rest) = match self.wire.split_first() {
397 Some((&actual, rest)) => (Some(actual), rest),
398 None => (None, self.wire),
399 };
400 if !matches!(actual, Some(actual) if actual == byte) {
401 return Err(Mismatch {
402 offset: self.offset,
403 expected: Some(byte),
404 actual,
405 });
406 }
407 self.wire = rest;
408 self.offset += 1;
409 index += 1;
410 }
411 Ok(())
412 }
413}