sark_http/field/metadata/packed/
mod.rs1use std::{mem, ops};
2
3use crate::field::{Indexing, metadata::map::record};
4
5mod decoded;
6pub mod prefix;
7
8pub use decoded::Decoded;
9use prefix::Prefix;
10use record::Entry;
11
12#[derive(Clone, Copy)]
13pub struct Iter<'a> {
14 current: &'a [u8],
15}
16
17pub struct RangeIter<'a> {
18 current: Iter<'a>,
19 offset: usize,
20}
21
22impl<'a> Iter<'a> {
23 pub(in crate::field::metadata) const fn new(current: &'a [u8]) -> Self {
24 Self { current }
25 }
26}
27
28impl<'a> RangeIter<'a> {
29 pub(in crate::field::metadata) fn new(current: &'a [u8], prefix: usize) -> Self {
30 Self {
31 current: Iter::new(¤t[prefix..]),
32 offset: prefix,
33 }
34 }
35}
36
37impl<'a> Iterator for Iter<'a> {
38 type Item = Entry<'a>;
39
40 fn next(&mut self) -> Option<Self::Item> {
41 if self.current.is_empty() {
42 return None;
43 }
44 let prefix = unsafe { &*self.current.as_ptr().cast::<[u8; Prefix::LEN]>() };
47 let prefix = Prefix::decode(prefix, Indexing::from_never(prefix[8] != 0));
48 let name_end = Prefix::LEN + prefix.name_len() as usize;
49 let end = name_end + prefix.value_len() as usize;
50 let field = unsafe {
53 let field = Entry::new(
54 self.current.get_unchecked(Prefix::LEN..name_end),
55 self.current.get_unchecked(name_end..end),
56 )
57 .with_index(prefix.indexing());
58 self.current = self.current.get_unchecked(end..);
59 field
60 };
61 Some(field)
62 }
63}
64
65impl<'a> Iterator for RangeIter<'a> {
66 type Item = (Entry<'a>, ops::Range<usize>);
67
68 fn next(&mut self) -> Option<Self::Item> {
69 let field = self.current.next()?;
70 let start = self.offset + Prefix::LEN + field.name.len();
71 self.offset = start + field.value.len();
72 Some((field, start..self.offset))
73 }
74}
75
76const _: () = assert!(mem::size_of::<Iter<'static>>() == mem::size_of::<&[u8]>());