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