Skip to main content

sark_core/http/
field.rs

1use std::convert::Infallible;
2use std::fmt;
3use std::ops::Range;
4
5use o3::buffer::{ByteSink, PoolLayoutError, Pooled, SharedPool, SharedPoolLayout};
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8pub struct Field<'a> {
9    pub name: &'a [u8],
10    pub value: &'a [u8],
11}
12
13impl<'a> Field<'a> {
14    pub const fn new(name: &'a [u8], value: &'a [u8]) -> Self {
15        Self { name, value }
16    }
17}
18
19impl<'field> From<&Field<'field>> for Field<'field> {
20    fn from(field: &Field<'field>) -> Self {
21        *field
22    }
23}
24
25#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct OwnedField {
27    pub name: Vec<u8>,
28    pub value: Vec<u8>,
29}
30
31impl OwnedField {
32    pub fn new(name: &[u8], value: &[u8]) -> Self {
33        Self {
34            name: name.to_vec(),
35            value: value.to_vec(),
36        }
37    }
38
39    pub fn as_ref(&self) -> Field<'_> {
40        Field::new(&self.name, &self.value)
41    }
42}
43
44impl From<Field<'_>> for OwnedField {
45    fn from(field: Field<'_>) -> Self {
46        Self::new(field.name, field.value)
47    }
48}
49
50impl<'a> From<&'a OwnedField> for Field<'a> {
51    fn from(field: &'a OwnedField) -> Self {
52        field.as_ref()
53    }
54}
55
56pub trait FieldStorage {
57    type Iter<'a>: Iterator<Item = Field<'a>>
58    where
59        Self: 'a;
60
61    fn fields(&self) -> Self::Iter<'_>;
62}
63
64#[derive(Clone)]
65pub struct FieldBlock<S> {
66    storage: S,
67}
68
69impl<S> FieldBlock<S> {
70    pub const fn from_storage(storage: S) -> Self {
71        Self { storage }
72    }
73
74    pub fn into_storage(self) -> S {
75        self.storage
76    }
77
78    pub fn storage(&self) -> &S {
79        &self.storage
80    }
81}
82
83impl<S: FieldStorage> FieldBlock<S> {
84    pub fn iter(&self) -> S::Iter<'_> {
85        self.storage.fields()
86    }
87
88    pub fn get(&self, name: &[u8]) -> Option<&[u8]> {
89        self.iter()
90            .find(|field| field.name == name)
91            .map(|field| field.value)
92    }
93}
94
95impl<S: FieldStorage> fmt::Debug for FieldBlock<S> {
96    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
97        formatter.debug_list().entries(self.iter()).finish()
98    }
99}
100
101impl<S, T> PartialEq<FieldBlock<T>> for FieldBlock<S>
102where
103    S: FieldStorage,
104    T: FieldStorage,
105{
106    fn eq(&self, other: &FieldBlock<T>) -> bool {
107        self.iter().eq(other.iter())
108    }
109}
110
111impl<S: FieldStorage> Eq for FieldBlock<S> {}
112
113impl<'a, S: FieldStorage> IntoIterator for &'a FieldBlock<S> {
114    type Item = Field<'a>;
115    type IntoIter = S::Iter<'a>;
116
117    fn into_iter(self) -> Self::IntoIter {
118        self.iter()
119    }
120}
121
122pub struct OwnedFieldIter<'a> {
123    fields: std::slice::Iter<'a, OwnedField>,
124}
125
126impl<'a> Iterator for OwnedFieldIter<'a> {
127    type Item = Field<'a>;
128
129    fn next(&mut self) -> Option<Self::Item> {
130        self.fields.next().map(OwnedField::as_ref)
131    }
132
133    fn size_hint(&self) -> (usize, Option<usize>) {
134        self.fields.size_hint()
135    }
136}
137
138impl ExactSizeIterator for OwnedFieldIter<'_> {}
139
140impl FieldStorage for Vec<OwnedField> {
141    type Iter<'a> = OwnedFieldIter<'a>;
142
143    fn fields(&self) -> Self::Iter<'_> {
144        OwnedFieldIter {
145            fields: self.iter(),
146        }
147    }
148}
149
150pub type OwnedFieldBlock = FieldBlock<Vec<OwnedField>>;
151
152impl FieldBlock<Vec<OwnedField>> {
153    pub const fn new() -> Self {
154        Self::from_storage(Vec::new())
155    }
156
157    pub fn push(&mut self, name: &[u8], value: &[u8]) {
158        self.storage.push(OwnedField::new(name, value));
159    }
160
161    pub fn as_slice(&self) -> &[OwnedField] {
162        &self.storage
163    }
164}
165
166impl Default for FieldBlock<Vec<OwnedField>> {
167    fn default() -> Self {
168        Self::new()
169    }
170}
171
172#[derive(Clone)]
173pub struct PackedFields<S> {
174    first: S,
175    second: Option<S>,
176}
177
178#[derive(Clone, Debug, PartialEq, Eq)]
179pub enum PackedFieldError<E> {
180    Write(E),
181    ComponentTooLarge { len: usize },
182    ValueLengthMismatch { expected: usize, actual: usize },
183}
184
185fn write_packed_prefix<W: ByteSink>(
186    writer: &mut W,
187    name: &[u8],
188    value_len: usize,
189) -> Result<(), PackedFieldError<W::Error>> {
190    let name_len = packed_len(name.len())?;
191    let value_len = packed_len(value_len)?;
192    writer
193        .write_slices([&name_len, &value_len, name])
194        .map_err(PackedFieldError::Write)
195}
196
197fn packed_len<E>(len: usize) -> Result<[u8; 4], PackedFieldError<E>> {
198    match u32::try_from(len) {
199        Ok(len) => Ok(len.to_ne_bytes()),
200        Err(_) => Err(PackedFieldError::ComponentTooLarge { len }),
201    }
202}
203
204fn write_packed_field<W: ByteSink>(
205    writer: &mut W,
206    field: Field<'_>,
207) -> Result<(), PackedFieldError<W::Error>> {
208    let name_len = packed_len(field.name.len())?;
209    let value_len = packed_len(field.value.len())?;
210    writer
211        .write_slices([&name_len, &value_len, field.name, field.value])
212        .map_err(PackedFieldError::Write)
213}
214
215fn packed_capacity(fields: &[Field<'_>]) -> Option<usize> {
216    fields.iter().try_fold(0usize, |size, field| {
217        u32::try_from(field.name.len()).ok()?;
218        u32::try_from(field.value.len()).ok()?;
219        field
220            .name
221            .len()
222            .checked_add(field.value.len())?
223            .checked_add(8)?
224            .checked_add(size)
225    })
226}
227
228impl<S> PackedFields<S> {
229    pub const fn new(first: S) -> Self {
230        Self {
231            first,
232            second: None,
233        }
234    }
235}
236
237impl<S: AsRef<[u8]>> FieldStorage for PackedFields<S> {
238    type Iter<'a>
239        = PackedFieldIter<'a>
240    where
241        S: 'a;
242
243    fn fields(&self) -> Self::Iter<'_> {
244        PackedFieldIter {
245            current: self.first.as_ref(),
246            second: self.second.as_ref().map(AsRef::as_ref),
247        }
248    }
249}
250
251pub type PooledFieldBlock = FieldBlock<PackedFields<Pooled>>;
252pub type VecFieldBlock = FieldBlock<PackedFields<Vec<u8>>>;
253
254impl FieldBlock<PackedFields<Pooled>> {
255    pub fn from_pooled(pooled: Pooled) -> Self {
256        Self::from_storage(PackedFields::new(pooled))
257    }
258
259    pub fn from_fields(fields: &[Field<'_>]) -> Result<Self, PoolLayoutError> {
260        let capacity = packed_capacity(fields).ok_or(PoolLayoutError::CapacityOverflow)?;
261        let layout = SharedPoolLayout::new(1, capacity.max(1))?;
262        let pool = SharedPool::from_layout(layout);
263        let mut lease = pool.try_acquire().ok_or(PoolLayoutError::SlotOverflow)?;
264        let mut writer = lease.spare_writer();
265        for field in fields {
266            write_packed_field(&mut writer, *field)
267                .map_err(|_| PoolLayoutError::CapacityOverflow)?;
268        }
269        drop(writer);
270        Ok(Self::from_pooled(lease.freeze()))
271    }
272
273    pub fn from_headers(fields: &[Field<'_>]) -> Result<Self, PoolLayoutError> {
274        Self::from_fields(fields)
275    }
276
277    pub fn append(&mut self, other: Self) -> Result<(), Self> {
278        if self.storage.second.is_some() || other.storage.second.is_some() {
279            return Err(other);
280        }
281        self.storage.second = Some(other.storage.first);
282        Ok(())
283    }
284
285    pub fn to_owned(&self) -> Vec<OwnedField> {
286        self.iter().map(OwnedField::from).collect()
287    }
288}
289
290impl FieldBlock<PackedFields<Vec<u8>>> {
291    pub const fn new() -> Self {
292        Self::from_storage(PackedFields::new(Vec::new()))
293    }
294
295    pub fn with_capacity(capacity: usize) -> Self {
296        Self::from_storage(PackedFields::new(Vec::with_capacity(capacity)))
297    }
298
299    pub fn push(&mut self, name: &[u8], value: &[u8]) -> Result<(), PackedFieldError<Infallible>> {
300        write_packed_field(&mut self.storage.first, Field::new(name, value))
301    }
302
303    pub fn push_encoded(
304        &mut self,
305        name: &[u8],
306        value_len: usize,
307        encode: impl FnOnce(&mut FieldValueWriter<'_>),
308    ) -> Result<(), PackedFieldError<Infallible>> {
309        let field_start = self.storage.first.len();
310        write_packed_prefix(&mut self.storage.first, name, value_len)?;
311        let start = self.storage.first.len();
312        encode(&mut FieldValueWriter {
313            bytes: &mut self.storage.first,
314        });
315        let actual = self.storage.first.len() - start;
316        if actual != value_len {
317            self.storage.first.truncate(field_start);
318            return Err(PackedFieldError::ValueLengthMismatch {
319                expected: value_len,
320                actual,
321            });
322        }
323        Ok(())
324    }
325
326    pub fn try_push_parts<E>(
327        &mut self,
328        encode_name: impl FnOnce(&mut FieldValueWriter<'_>) -> Result<(), E>,
329        encode_value: impl FnOnce(&mut FieldValueWriter<'_>, usize) -> Result<(), E>,
330    ) -> Result<(usize, usize), PackedFieldError<E>> {
331        let field_start = self.storage.first.len();
332        self.storage.first.extend_from_slice(&[0; 8]);
333        let name_start = self.storage.first.len();
334        if let Err(error) = encode_name(&mut FieldValueWriter {
335            bytes: &mut self.storage.first,
336        }) {
337            self.storage.first.truncate(field_start);
338            return Err(PackedFieldError::Write(error));
339        }
340        let value_start = self.storage.first.len();
341        let name_len = value_start - name_start;
342        if let Err(error) = encode_value(
343            &mut FieldValueWriter {
344                bytes: &mut self.storage.first,
345            },
346            name_len,
347        ) {
348            self.storage.first.truncate(field_start);
349            return Err(PackedFieldError::Write(error));
350        }
351        let end = self.storage.first.len();
352        let value_len = end - value_start;
353        let name_len_bytes = match packed_len(name_len) {
354            Ok(len) => len,
355            Err(error) => {
356                self.storage.first.truncate(field_start);
357                return Err(error);
358            }
359        };
360        let value_len_bytes = match packed_len(value_len) {
361            Ok(len) => len,
362            Err(error) => {
363                self.storage.first.truncate(field_start);
364                return Err(error);
365            }
366        };
367        self.storage.first[field_start..field_start + 4].copy_from_slice(&name_len_bytes);
368        self.storage.first[field_start + 4..name_start].copy_from_slice(&value_len_bytes);
369        Ok((name_len, value_len))
370    }
371
372    pub fn as_bytes(&self) -> &[u8] {
373        &self.storage.first
374    }
375
376    pub fn iter_with_value_ranges(&self) -> PackedFieldRangeIter<'_> {
377        PackedFieldRangeIter {
378            current: &self.storage.first,
379            offset: 0,
380        }
381    }
382}
383
384impl Default for FieldBlock<PackedFields<Vec<u8>>> {
385    fn default() -> Self {
386        Self::new()
387    }
388}
389
390pub struct FieldValueWriter<'a> {
391    bytes: &'a mut Vec<u8>,
392}
393
394impl FieldValueWriter<'_> {
395    pub fn push(&mut self, byte: u8) {
396        self.bytes.push(byte);
397    }
398
399    pub fn extend_from_slice(&mut self, bytes: &[u8]) {
400        self.bytes.extend_from_slice(bytes);
401    }
402}
403
404pub struct PackedFieldIter<'a> {
405    current: &'a [u8],
406    second: Option<&'a [u8]>,
407}
408
409impl<'a> Iterator for PackedFieldIter<'a> {
410    type Item = Field<'a>;
411
412    fn next(&mut self) -> Option<Self::Item> {
413        if self.current.is_empty() {
414            self.current = self.second.take()?;
415        }
416        let Some((field, _, end)) = parse_packed_field(self.current) else {
417            self.current = &[];
418            self.second = None;
419            return None;
420        };
421        self.current = &self.current[end..];
422        Some(field)
423    }
424}
425
426pub struct PackedFieldRangeIter<'a> {
427    current: &'a [u8],
428    offset: usize,
429}
430
431impl<'a> Iterator for PackedFieldRangeIter<'a> {
432    type Item = (Field<'a>, Range<usize>);
433
434    fn next(&mut self) -> Option<Self::Item> {
435        let Some((field, value_start, end)) = parse_packed_field(self.current) else {
436            self.current = &[];
437            return None;
438        };
439        let value_range = self.offset + value_start..self.offset + end;
440        self.current = &self.current[end..];
441        self.offset += end;
442        Some((field, value_range))
443    }
444}
445
446fn parse_packed_field(bytes: &[u8]) -> Option<(Field<'_>, usize, usize)> {
447    if bytes.len() < 8 {
448        return None;
449    }
450    let name_len = u32::from_ne_bytes(bytes[..4].try_into().ok()?) as usize;
451    let value_len = u32::from_ne_bytes(bytes[4..8].try_into().ok()?) as usize;
452    let value_start = 8usize.checked_add(name_len)?;
453    let end = value_start.checked_add(value_len)?;
454    if end > bytes.len() {
455        return None;
456    }
457    Some((
458        Field::new(&bytes[8..value_start], &bytes[value_start..end]),
459        value_start,
460        end,
461    ))
462}