Skip to main content

packet/
serialize.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Serialization.
6
7use alloc::vec;
8use alloc::vec::Vec;
9use core::cmp;
10use core::fmt::{self, Debug, Formatter};
11use core::marker::PhantomData;
12use core::ops::{Range, RangeBounds};
13
14use arrayvec::ArrayVec;
15use zerocopy::SplitByteSlice;
16
17use crate::{
18    AsFragmentedByteSlice, Buffer, BufferView, BufferViewMut, ContiguousBuffer, EmptyBuf,
19    FragmentedBuffer, FragmentedBufferMut, FragmentedBytes, FragmentedBytesMut, GrowBuffer,
20    GrowBufferMut, ParsablePacket, ParseBuffer, ParseBufferMut, ReusableBuffer, ShrinkBuffer,
21    canonicalize_range,
22};
23
24/// Either of two buffers.
25///
26/// An `Either` wraps one of two different buffer types. It implements all of
27/// the relevant traits by calling the corresponding methods on the wrapped
28/// buffer.
29#[derive(Copy, Clone, Debug)]
30pub enum Either<A, B> {
31    A(A),
32    B(B),
33}
34
35impl<A, B> Either<A, B> {
36    /// Maps the `A` variant of an `Either`.
37    ///
38    /// Given an `Either<A, B>` and a function from `A` to `AA`, `map_a`
39    /// produces an `Either<AA, B>` by applying the function to the `A` variant
40    /// or passing on the `B` variant unmodified.
41    pub fn map_a<AA, F: FnOnce(A) -> AA>(self, f: F) -> Either<AA, B> {
42        match self {
43            Either::A(a) => Either::A(f(a)),
44            Either::B(b) => Either::B(b),
45        }
46    }
47
48    /// Maps the `B` variant of an `Either`.
49    ///
50    /// Given an `Either<A, B>` and a function from `B` to `BB`, `map_b`
51    /// produces an `Either<A, BB>` by applying the function to the `B` variant
52    /// or passing on the `A` variant unmodified.
53    pub fn map_b<BB, F: FnOnce(B) -> BB>(self, f: F) -> Either<A, BB> {
54        match self {
55            Either::A(a) => Either::A(a),
56            Either::B(b) => Either::B(f(b)),
57        }
58    }
59
60    /// Returns the `A` variant in an `Either<A, B>`.
61    ///
62    /// # Panics
63    ///
64    /// Panics if this `Either<A, B>` does not hold the `A` variant.
65    pub fn unwrap_a(self) -> A {
66        match self {
67            Either::A(x) => x,
68            Either::B(_) => panic!("This `Either<A, B>` does not hold the `A` variant"),
69        }
70    }
71
72    /// Returns the `B` variant in an `Either<A, B>`.
73    ///
74    /// # Panics
75    ///
76    /// Panics if this `Either<A, B>` does not hold the `B` variant.
77    pub fn unwrap_b(self) -> B {
78        match self {
79            Either::A(_) => panic!("This `Either<A, B>` does not hold the `B` variant"),
80            Either::B(x) => x,
81        }
82    }
83}
84
85impl<A> Either<A, A> {
86    /// Returns the inner value held by this `Either` when both possible values
87    /// `Either::A` and `Either::B` contain the same inner types.
88    pub fn into_inner(self) -> A {
89        match self {
90            Either::A(x) => x,
91            Either::B(x) => x,
92        }
93    }
94}
95
96impl<A> Either<A, !> {
97    /// Returns the `A` value in an `Either<A, !>`.
98    #[inline]
99    pub fn into_a(self) -> A {
100        match self {
101            Either::A(a) => a,
102        }
103    }
104}
105
106impl<B> Either<!, B> {
107    /// Returns the `B` value in an `Either<!, B>`.
108    #[inline]
109    pub fn into_b(self) -> B {
110        match self {
111            Either::B(b) => b,
112        }
113    }
114}
115
116macro_rules! call_method_on_either {
117    ($val:expr, $method:ident, $($args:expr),*) => {
118        match $val {
119            Either::A(a) => a.$method($($args),*),
120            Either::B(b) => b.$method($($args),*),
121        }
122    };
123    ($val:expr, $method:ident) => {
124        call_method_on_either!($val, $method,)
125    };
126}
127
128// NOTE(joshlf): We override the default implementations of all methods for
129// Either. Many of the default implementations make multiple calls to other
130// Buffer methods, each of which performs a match statement to figure out which
131// Either variant is present. We assume that doing this match once is more
132// performant than doing it multiple times.
133
134impl<A, B> FragmentedBuffer for Either<A, B>
135where
136    A: FragmentedBuffer,
137    B: FragmentedBuffer,
138{
139    fn len(&self) -> usize {
140        call_method_on_either!(self, len)
141    }
142
143    fn with_bytes<'a, R, F>(&'a self, f: F) -> R
144    where
145        F: for<'b> FnOnce(FragmentedBytes<'b, 'a>) -> R,
146    {
147        call_method_on_either!(self, with_bytes, f)
148    }
149}
150
151impl<A, B> ContiguousBuffer for Either<A, B>
152where
153    A: ContiguousBuffer,
154    B: ContiguousBuffer,
155{
156}
157
158impl<A, B> ShrinkBuffer for Either<A, B>
159where
160    A: ShrinkBuffer,
161    B: ShrinkBuffer,
162{
163    fn shrink<R: RangeBounds<usize>>(&mut self, range: R) {
164        call_method_on_either!(self, shrink, range)
165    }
166    fn shrink_front(&mut self, n: usize) {
167        call_method_on_either!(self, shrink_front, n)
168    }
169    fn shrink_back(&mut self, n: usize) {
170        call_method_on_either!(self, shrink_back, n)
171    }
172}
173
174impl<A, B> ParseBuffer for Either<A, B>
175where
176    A: ParseBuffer,
177    B: ParseBuffer,
178{
179    fn parse<'a, P: ParsablePacket<&'a [u8], ()>>(&'a mut self) -> Result<P, P::Error> {
180        call_method_on_either!(self, parse)
181    }
182    fn parse_with<'a, ParseArgs, P: ParsablePacket<&'a [u8], ParseArgs>>(
183        &'a mut self,
184        args: ParseArgs,
185    ) -> Result<P, P::Error> {
186        call_method_on_either!(self, parse_with, args)
187    }
188}
189
190impl<A, B> FragmentedBufferMut for Either<A, B>
191where
192    A: FragmentedBufferMut,
193    B: FragmentedBufferMut,
194{
195    fn with_bytes_mut<'a, R, F>(&'a mut self, f: F) -> R
196    where
197        F: for<'b> FnOnce(FragmentedBytesMut<'b, 'a>) -> R,
198    {
199        call_method_on_either!(self, with_bytes_mut, f)
200    }
201}
202
203impl<A, B> ParseBufferMut for Either<A, B>
204where
205    A: ParseBufferMut,
206    B: ParseBufferMut,
207{
208    fn parse_mut<'a, P: ParsablePacket<&'a mut [u8], ()>>(&'a mut self) -> Result<P, P::Error> {
209        call_method_on_either!(self, parse_mut)
210    }
211    fn parse_with_mut<'a, ParseArgs, P: ParsablePacket<&'a mut [u8], ParseArgs>>(
212        &'a mut self,
213        args: ParseArgs,
214    ) -> Result<P, P::Error> {
215        call_method_on_either!(self, parse_with_mut, args)
216    }
217}
218
219impl<A, B> GrowBuffer for Either<A, B>
220where
221    A: GrowBuffer,
222    B: GrowBuffer,
223{
224    #[inline]
225    fn with_parts<'a, O, F>(&'a self, f: F) -> O
226    where
227        F: for<'b> FnOnce(&'a [u8], FragmentedBytes<'b, 'a>, &'a [u8]) -> O,
228    {
229        call_method_on_either!(self, with_parts, f)
230    }
231    fn capacity(&self) -> usize {
232        call_method_on_either!(self, capacity)
233    }
234    fn prefix_len(&self) -> usize {
235        call_method_on_either!(self, prefix_len)
236    }
237    fn suffix_len(&self) -> usize {
238        call_method_on_either!(self, suffix_len)
239    }
240    fn grow_front(&mut self, n: usize) {
241        call_method_on_either!(self, grow_front, n)
242    }
243    fn grow_back(&mut self, n: usize) {
244        call_method_on_either!(self, grow_back, n)
245    }
246    fn reset(&mut self) {
247        call_method_on_either!(self, reset)
248    }
249}
250
251impl<A, B> GrowBufferMut for Either<A, B>
252where
253    A: GrowBufferMut,
254    B: GrowBufferMut,
255{
256    fn with_parts_mut<'a, O, F>(&'a mut self, f: F) -> O
257    where
258        F: for<'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'b, 'a>, &'a mut [u8]) -> O,
259    {
260        call_method_on_either!(self, with_parts_mut, f)
261    }
262
263    fn with_all_contents_mut<'a, O, F>(&'a mut self, f: F) -> O
264    where
265        F: for<'b> FnOnce(FragmentedBytesMut<'b, 'a>) -> O,
266    {
267        call_method_on_either!(self, with_all_contents_mut, f)
268    }
269
270    fn serialize<C: SerializationContext, BB: PacketBuilder<C>>(
271        &mut self,
272        context: &mut C,
273        builder: BB,
274    ) {
275        call_method_on_either!(self, serialize, context, builder)
276    }
277}
278
279impl<A, B> Buffer for Either<A, B>
280where
281    A: Buffer,
282    B: Buffer,
283{
284    fn parse_with_view<'a, ParseArgs, P: ParsablePacket<&'a [u8], ParseArgs>>(
285        &'a mut self,
286        args: ParseArgs,
287    ) -> Result<(P, &'a [u8]), P::Error> {
288        call_method_on_either!(self, parse_with_view, args)
289    }
290}
291
292impl<A: AsRef<[u8]>, B: AsRef<[u8]>> AsRef<[u8]> for Either<A, B> {
293    fn as_ref(&self) -> &[u8] {
294        call_method_on_either!(self, as_ref)
295    }
296}
297
298impl<A: AsMut<[u8]>, B: AsMut<[u8]>> AsMut<[u8]> for Either<A, B> {
299    fn as_mut(&mut self) -> &mut [u8] {
300        call_method_on_either!(self, as_mut)
301    }
302}
303
304/// A byte slice wrapper providing buffer functionality.
305///
306/// A `Buf` wraps a byte slice (a type which implements `AsRef<[u8]>` or
307/// `AsMut<[u8]>`) and implements various buffer traits by keeping track of
308/// prefix, body, and suffix offsets within the byte slice.
309#[derive(Clone, Debug)]
310pub struct Buf<B> {
311    buf: B,
312    body: Range<usize>,
313}
314
315impl<B: AsRef<[u8]>> PartialEq for Buf<B> {
316    fn eq(&self, other: &Self) -> bool {
317        let self_slice = AsRef::<[u8]>::as_ref(self);
318        let other_slice = AsRef::<[u8]>::as_ref(other);
319        PartialEq::eq(self_slice, other_slice)
320    }
321}
322
323impl<B: AsRef<[u8]>> Eq for Buf<B> {}
324
325impl Buf<Vec<u8>> {
326    /// Extracts the contained data trimmed to the buffer's range.
327    pub fn into_inner(self) -> Vec<u8> {
328        let Buf { mut buf, body } = self;
329        let len = body.end - body.start;
330        let _ = buf.drain(..body.start);
331        buf.truncate(len);
332        buf
333    }
334}
335
336impl<B> Buf<B> {
337    /// Extracts the underlying buffer and the range.
338    pub fn into_parts(self) -> (B, Range<usize>) {
339        let Buf { buf, body } = self;
340        (buf, body)
341    }
342}
343
344impl<B: AsRef<[u8]>> Buf<B> {
345    /// Constructs a new `Buf`.
346    ///
347    /// `new` constructs a new `Buf` from a buffer and a body range. The bytes
348    /// within the range will be the body, the bytes before the range will be
349    /// the prefix, and the bytes after the range will be the suffix.
350    ///
351    /// # Panics
352    ///
353    /// Panics if `range` is out of bounds of `buf`, or if it is nonsensical
354    /// (the end precedes the start).
355    pub fn new<R: RangeBounds<usize>>(buf: B, body: R) -> Buf<B> {
356        let len = buf.as_ref().len();
357        Buf { buf, body: canonicalize_range(len, &body) }
358    }
359
360    /// Constructs a [`BufView`] which will be a [`BufferView`] into this `Buf`.
361    pub fn buffer_view(&mut self) -> BufView<'_> {
362        BufView { buf: &self.buf.as_ref()[self.body.clone()], body: &mut self.body }
363    }
364}
365
366impl<B: AsRef<[u8]> + AsMut<[u8]>> Buf<B> {
367    /// Constructs a [`BufViewMut`] which will be a [`BufferViewMut`] into this `Buf`.
368    pub fn buffer_view_mut(&mut self) -> BufViewMut<'_> {
369        BufViewMut { buf: &mut self.buf.as_mut()[self.body.clone()], body: &mut self.body }
370    }
371}
372
373impl<B: AsRef<[u8]>> FragmentedBuffer for Buf<B> {
374    fragmented_buffer_method_impls!();
375}
376impl<B: AsRef<[u8]>> ContiguousBuffer for Buf<B> {}
377impl<B: AsRef<[u8]>> ShrinkBuffer for Buf<B> {
378    fn shrink<R: RangeBounds<usize>>(&mut self, range: R) {
379        let len = self.len();
380        let mut range = canonicalize_range(len, &range);
381        range.start += self.body.start;
382        range.end += self.body.start;
383        self.body = range;
384    }
385
386    fn shrink_front(&mut self, n: usize) {
387        assert!(n <= self.len());
388        self.body.start += n;
389    }
390    fn shrink_back(&mut self, n: usize) {
391        assert!(n <= self.len());
392        self.body.end -= n;
393    }
394}
395impl<B: AsRef<[u8]>> ParseBuffer for Buf<B> {
396    fn parse_with<'a, ParseArgs, P: ParsablePacket<&'a [u8], ParseArgs>>(
397        &'a mut self,
398        args: ParseArgs,
399    ) -> Result<P, P::Error> {
400        P::parse(self.buffer_view(), args)
401    }
402}
403
404impl<B: AsRef<[u8]> + AsMut<[u8]>> FragmentedBufferMut for Buf<B> {
405    fragmented_buffer_mut_method_impls!();
406}
407
408impl<B: AsRef<[u8]> + AsMut<[u8]>> ParseBufferMut for Buf<B> {
409    fn parse_with_mut<'a, ParseArgs, P: ParsablePacket<&'a mut [u8], ParseArgs>>(
410        &'a mut self,
411        args: ParseArgs,
412    ) -> Result<P, P::Error> {
413        P::parse_mut(self.buffer_view_mut(), args)
414    }
415}
416
417impl<B: AsRef<[u8]>> GrowBuffer for Buf<B> {
418    fn with_parts<'a, O, F>(&'a self, f: F) -> O
419    where
420        F: for<'b> FnOnce(&'a [u8], FragmentedBytes<'b, 'a>, &'a [u8]) -> O,
421    {
422        let (prefix, buf) = self.buf.as_ref().split_at(self.body.start);
423        let (body, suffix) = buf.split_at(self.body.end - self.body.start);
424        let mut body = [&body[..]];
425        f(prefix, body.as_fragmented_byte_slice(), suffix)
426    }
427    fn capacity(&self) -> usize {
428        self.buf.as_ref().len()
429    }
430    fn prefix_len(&self) -> usize {
431        self.body.start
432    }
433    fn suffix_len(&self) -> usize {
434        self.buf.as_ref().len() - self.body.end
435    }
436    fn grow_front(&mut self, n: usize) {
437        assert!(n <= self.body.start);
438        self.body.start -= n;
439    }
440    fn grow_back(&mut self, n: usize) {
441        assert!(n <= self.buf.as_ref().len() - self.body.end);
442        self.body.end += n;
443    }
444}
445
446impl<B: AsRef<[u8]> + AsMut<[u8]>> GrowBufferMut for Buf<B> {
447    fn with_parts_mut<'a, O, F>(&'a mut self, f: F) -> O
448    where
449        F: for<'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'b, 'a>, &'a mut [u8]) -> O,
450    {
451        let (prefix, buf) = self.buf.as_mut().split_at_mut(self.body.start);
452        let (body, suffix) = buf.split_at_mut(self.body.end - self.body.start);
453        let mut body = [&mut body[..]];
454        f(prefix, body.as_fragmented_byte_slice(), suffix)
455    }
456
457    fn with_all_contents_mut<'a, O, F>(&'a mut self, f: F) -> O
458    where
459        F: for<'b> FnOnce(FragmentedBytesMut<'b, 'a>) -> O,
460    {
461        let mut all = [self.buf.as_mut()];
462        f(all.as_fragmented_byte_slice())
463    }
464}
465
466impl<B: AsRef<[u8]>> AsRef<[u8]> for Buf<B> {
467    fn as_ref(&self) -> &[u8] {
468        &self.buf.as_ref()[self.body.clone()]
469    }
470}
471
472impl<B: AsMut<[u8]>> AsMut<[u8]> for Buf<B> {
473    fn as_mut(&mut self) -> &mut [u8] {
474        &mut self.buf.as_mut()[self.body.clone()]
475    }
476}
477
478impl<B: AsRef<[u8]>> Buffer for Buf<B> {
479    fn parse_with_view<'a, ParseArgs, P: ParsablePacket<&'a [u8], ParseArgs>>(
480        &'a mut self,
481        args: ParseArgs,
482    ) -> Result<(P, &'a [u8]), P::Error> {
483        let &mut Self { ref mut body, ref buf } = self;
484        let body_before = body.clone();
485        let view = BufView { buf: &buf.as_ref()[body.clone()], body };
486        P::parse(view, args).map(|r| (r, &buf.as_ref()[body_before]))
487    }
488}
489
490/// A [`BufferView`] into a [`Buf`].
491///
492/// A `BufView` is constructed by [`Buf::buffer_view`], and implements
493/// `BufferView`, providing a view into the `Buf` from which it was constructed.
494pub struct BufView<'a> {
495    buf: &'a [u8],
496    body: &'a mut Range<usize>,
497}
498
499impl<'a> BufferView<&'a [u8]> for BufView<'a> {
500    fn take_front(&mut self, n: usize) -> Option<&'a [u8]> {
501        if self.len() < n {
502            return None;
503        }
504        self.body.start += n;
505        self.buf.split_off(..n)
506    }
507
508    fn take_back(&mut self, n: usize) -> Option<&'a [u8]> {
509        if self.len() < n {
510            return None;
511        }
512        self.body.end -= n;
513
514        let split = <[u8]>::len(self.buf).checked_sub(n).unwrap();
515        self.buf.split_off(split..)
516    }
517
518    fn into_rest(self) -> &'a [u8] {
519        self.buf
520    }
521}
522
523impl<'a> AsRef<[u8]> for BufView<'a> {
524    fn as_ref(&self) -> &[u8] {
525        self.buf
526    }
527}
528
529/// A [`BufferViewMut`] into a [`Buf`].
530///
531/// A `BufViewMut` is constructed by [`Buf::buffer_view_mut`], and implements
532/// `BufferViewMut`, providing a mutable view into the `Buf` from which it was
533/// constructed.
534pub struct BufViewMut<'a> {
535    buf: &'a mut [u8],
536    body: &'a mut Range<usize>,
537}
538
539impl<'a> BufferView<&'a mut [u8]> for BufViewMut<'a> {
540    fn take_front(&mut self, n: usize) -> Option<&'a mut [u8]> {
541        if self.len() < n {
542            return None;
543        }
544        self.body.start += n;
545        self.buf.split_off_mut(..n)
546    }
547
548    fn take_back(&mut self, n: usize) -> Option<&'a mut [u8]> {
549        if self.len() < n {
550            return None;
551        }
552        self.body.end -= n;
553
554        let split = <[u8]>::len(self.buf).checked_sub(n)?;
555        Some(self.buf.split_off_mut(split..)?)
556    }
557
558    fn into_rest(self) -> &'a mut [u8] {
559        self.buf
560    }
561}
562
563impl<'a> BufferViewMut<&'a mut [u8]> for BufViewMut<'a> {}
564
565impl<'a> AsRef<[u8]> for BufViewMut<'a> {
566    fn as_ref(&self) -> &[u8] {
567        self.buf
568    }
569}
570
571impl<'a> AsMut<[u8]> for BufViewMut<'a> {
572    fn as_mut(&mut self) -> &mut [u8] {
573        self.buf
574    }
575}
576
577/// The constraints required by a [`PacketBuilder`].
578///
579/// `PacketConstraints` represents the constraints that must be satisfied in
580/// order to serialize a `PacketBuilder`.
581///
582/// A `PacketConstraints`, `c`, guarantees two properties:
583/// - `c.max_body_len() >= c.min_body_len()`
584/// - `c.header_len() + c.min_body_len() + c.footer_len()` does not overflow
585///   `usize`
586///
587/// It is not possible (using safe code) to obtain a `PacketConstraints` which
588/// violates these properties, so code may rely for its correctness on the
589/// assumption that these properties hold.
590#[derive(Copy, Clone, Debug, Eq, PartialEq)]
591pub struct PacketConstraints {
592    header_len: usize,
593    footer_len: usize,
594    min_body_len: usize,
595    max_body_len: usize,
596}
597
598impl PacketConstraints {
599    /// A no-op `PacketConstraints` which does not add any constraints - there
600    /// is no header, footer, minimum body length requirement, or maximum body
601    /// length requirement.
602    pub const UNCONSTRAINED: Self =
603        Self { header_len: 0, footer_len: 0, min_body_len: 0, max_body_len: usize::MAX };
604
605    /// Constructs a new `PacketConstraints`.
606    ///
607    /// # Panics
608    ///
609    /// `new` panics if the arguments violate the validity properties of
610    /// `PacketConstraints` - if `max_body_len < min_body_len`, or if
611    /// `header_len + min_body_len + footer_len` overflows `usize`.
612    #[inline]
613    pub fn new(
614        header_len: usize,
615        footer_len: usize,
616        min_body_len: usize,
617        max_body_len: usize,
618    ) -> PacketConstraints {
619        PacketConstraints::try_new(header_len, footer_len, min_body_len, max_body_len).expect(
620            "max_body_len < min_body_len or header_len + min_body_len + footer_len overflows usize",
621        )
622    }
623
624    /// Tries to construct a new `PacketConstraints`.
625    ///
626    /// `new` returns `None` if the provided values violate the validity
627    /// properties of `PacketConstraints` - if `max_body_len < min_body_len`, or
628    /// if `header_len + min_body_len + footer_len` overflows `usize`.
629    #[inline]
630    pub fn try_new(
631        header_len: usize,
632        footer_len: usize,
633        min_body_len: usize,
634        max_body_len: usize,
635    ) -> Option<PacketConstraints> {
636        // Test case 3 in test_packet_constraints
637        let header_min_body_footer_overflows = header_len
638            .checked_add(min_body_len)
639            .and_then(|sum| sum.checked_add(footer_len))
640            .is_none();
641        // Test case 5 in test_packet_constraints
642        let max_less_than_min = max_body_len < min_body_len;
643        if max_less_than_min || header_min_body_footer_overflows {
644            return None;
645        }
646        Some(PacketConstraints { header_len, footer_len, min_body_len, max_body_len })
647    }
648
649    /// Constructs a new `PacketConstraints` with a given `max_body_len`.
650    ///
651    /// The `header_len`, `footer_len`, and `min_body_len` are all `0`.
652    #[inline]
653    pub fn with_max_body_len(max_body_len: usize) -> PacketConstraints {
654        // SAFETY:
655        // - `max_body_len >= min_body_len` by construction
656        // - `header_len + min_body_len + footer_len` is 0 and thus does not
657        //   overflow `usize`
658        PacketConstraints { header_len: 0, footer_len: 0, min_body_len: 0, max_body_len }
659    }
660
661    /// The number of bytes in this packet's header.
662    #[inline]
663    pub fn header_len(&self) -> usize {
664        self.header_len
665    }
666
667    /// The number of bytes in this packet's footer.
668    #[inline]
669    pub fn footer_len(&self) -> usize {
670        self.footer_len
671    }
672
673    /// The minimum body length (in bytes) required by this packet in order to
674    /// avoid adding padding.
675    ///
676    /// `min_body_len` returns the minimum number of body bytes required in
677    /// order to avoid adding padding. Note that, if padding bytes are required,
678    /// they may not necessarily belong immediately following the body,
679    /// depending on which packet layer imposes the minimum. In particular, in a
680    /// nested packet, padding goes after the body of the layer which imposes
681    /// the minimum. This means that, if the layer that imposes the minimum is
682    /// not the innermost one, then padding must be added not after the
683    /// innermost body, but instead in between footers.
684    /// [`NestedPacketBuilder::serialize_into`] is responsible for inserting
685    /// padding when serializing nested packets.
686    ///
687    /// If there is no minimum body length, this returns 0.
688    #[inline]
689    pub fn min_body_len(&self) -> usize {
690        self.min_body_len
691    }
692
693    /// The maximum length (in bytes) of a body allowed by this packet.
694    ///
695    /// If there is no maximum body length, this returns [`core::usize::MAX`].
696    #[inline]
697    pub fn max_body_len(&self) -> usize {
698        self.max_body_len
699    }
700
701    /// Attempts to encapsulate `self` in `outer`.
702    ///
703    /// Upon success, `try_encapsulate` returns a `PacketConstraints` which
704    /// represents the encapsulation of `self` in `outer`. Its header length,
705    /// footer length, minimum body length, and maximum body length are set
706    /// accordingly.
707    ///
708    /// This is probably not the method you want to use; consider
709    /// [`Serializer::encapsulate`] instead.
710    pub fn try_encapsulate(&self, outer: &Self) -> Option<PacketConstraints> {
711        let inner = self;
712        // Test case 1 in test_packet_constraints
713        let header_len = inner.header_len.checked_add(outer.header_len)?;
714        // Test case 2 in test_packet_constraints
715        let footer_len = inner.footer_len.checked_add(outer.footer_len)?;
716        // This is guaranteed not to overflow by the invariants on
717        // PacketConstraint.
718        let inner_header_footer_len = inner.header_len + inner.footer_len;
719        // Note the saturating_sub here - it's OK if the inner PacketBuilder
720        // more than satisfies the outer PacketBuilder's minimum body length
721        // requirement.
722        let min_body_len = cmp::max(
723            outer.min_body_len.saturating_sub(inner_header_footer_len),
724            inner.min_body_len,
725        );
726        // Note the checked_sub here - it's NOT OK if the inner PacketBuilder
727        // exceeds the outer PacketBuilder's maximum body length requirement.
728        //
729        // Test case 4 in test_packet_constraints
730        let max_body_len =
731            cmp::min(outer.max_body_len.checked_sub(inner_header_footer_len)?, inner.max_body_len);
732        // It's still possible that `min_body_len > max_body_len` or that
733        // `header_len + min_body_len + footer_len` overflows `usize`; `try_new`
734        // checks those constraints for us.
735        PacketConstraints::try_new(header_len, footer_len, min_body_len, max_body_len)
736    }
737}
738
739/// The target buffers into which [`PacketBuilder::serialize`] serializes its
740/// header and footer.
741pub struct SerializeTarget<'a> {
742    #[allow(missing_docs)]
743    pub header: &'a mut [u8],
744    #[allow(missing_docs)]
745    pub footer: &'a mut [u8],
746}
747
748/// A builder capable of serializing a packet's headers and footers.
749///
750/// A `PacketBuilder` describes a packet's headers and footers, and is capable
751/// of serializing the header and the footer into an existing buffer via the
752/// `serialize` method. A `PacketBuilder` never describes a body.
753/// [`NestablePacketBuilder::wrap_body`] must be used to create a packet
754/// serializer for a whole packet.
755///
756/// `()` may be used as an "empty" `PacketBuilder` with no header, footer,
757/// minimum body length requirement, or maximum body length requirement.
758pub trait PacketBuilder<C: SerializationContext>: NestablePacketBuilder + Sized {
759    /// Gets the packet-specific state to use with the [`SerializationContext`].
760    fn context_state(&self) -> C::ContextState {
761        C::ContextState::default()
762    }
763
764    /// Serializes this packet into an existing buffer.
765    ///
766    /// *This method is usually called by this crate during the serialization of
767    /// a [`Serializer`], not directly by the user.*
768    ///
769    /// # Preconditions
770    ///
771    /// The caller is responsible for initializing `body` with the body to be
772    /// encapsulated, and for ensuring that the body satisfies both the minimum
773    /// and maximum body length requirements, possibly by adding padding or by
774    /// truncating the body.
775    ///
776    /// # Postconditions
777    ///
778    /// `serialize` is responsible for serializing its header and footer into
779    /// `target.header` and `target.footer` respectively.
780    ///
781    /// # Security
782    ///
783    /// `serialize` must initialize the bytes of the header and footer, even if
784    /// only to zero, in order to avoid leaking the contents of packets
785    /// previously stored in the same buffer.
786    ///
787    /// # Panics
788    ///
789    /// May panic if the `target.header` or `target.footer` are not large enough
790    /// to fit the packet's header and footer respectively, or if the body does
791    /// not satisfy the minimum or maximum body length requirements.
792    fn serialize(
793        &self,
794        context: &mut C,
795        target: &mut SerializeTarget<'_>,
796        body: FragmentedBytesMut<'_, '_>,
797    );
798}
799
800pub trait NestablePacketBuilder: Sized {
801    /// Gets the constraints for this `PacketBuilder`.
802    fn constraints(&self) -> PacketConstraints;
803
804    /// Wraps given packet `body` in this packet.
805    ///
806    /// Consumes the [`PacketBuilder`] and the `body`. If the `body` implements
807    /// `Serializer` then the result implement `Serializer` as well.
808    #[inline]
809    fn wrap_body<B>(self, body: B) -> Nested<B, Self> {
810        Nested { inner: body, outer: self }
811    }
812}
813
814impl<'a, B: NestablePacketBuilder> NestablePacketBuilder for &'a B {
815    #[inline]
816    fn constraints(&self) -> PacketConstraints {
817        B::constraints(self)
818    }
819}
820
821impl<'a, C: SerializationContext, B: PacketBuilder<C>> PacketBuilder<C> for &'a B {
822    #[inline]
823    fn context_state(&self) -> C::ContextState {
824        B::context_state(self)
825    }
826    #[inline]
827    fn serialize(
828        &self,
829        context: &mut C,
830        target: &mut SerializeTarget<'_>,
831        body: FragmentedBytesMut<'_, '_>,
832    ) {
833        B::serialize(self, context, target, body)
834    }
835}
836
837impl<'a, B: NestablePacketBuilder> NestablePacketBuilder for &'a mut B {
838    #[inline]
839    fn constraints(&self) -> PacketConstraints {
840        B::constraints(self)
841    }
842}
843
844impl<'a, C: SerializationContext, B: PacketBuilder<C>> PacketBuilder<C> for &'a mut B {
845    #[inline]
846    fn context_state(&self) -> C::ContextState {
847        B::context_state(self)
848    }
849    #[inline]
850    fn serialize(
851        &self,
852        context: &mut C,
853        target: &mut SerializeTarget<'_>,
854        body: FragmentedBytesMut<'_, '_>,
855    ) {
856        B::serialize(self, context, target, body)
857    }
858}
859
860impl NestablePacketBuilder for () {
861    #[inline]
862    fn constraints(&self) -> PacketConstraints {
863        PacketConstraints::UNCONSTRAINED
864    }
865}
866
867impl<C: SerializationContext> PacketBuilder<C> for () {
868    #[inline]
869    fn serialize(
870        &self,
871        _context: &mut C,
872        _target: &mut SerializeTarget<'_>,
873        _body: FragmentedBytesMut<'_, '_>,
874    ) {
875    }
876}
877
878impl NestablePacketBuilder for ! {
879    fn constraints(&self) -> PacketConstraints {
880        match *self {}
881    }
882}
883
884impl<C: SerializationContext> PacketBuilder<C> for ! {
885    fn serialize(
886        &self,
887        _context: &mut C,
888        _target: &mut SerializeTarget<'_>,
889        _body: FragmentedBytesMut<'_, '_>,
890    ) {
891    }
892}
893
894/// One object encapsulated in another one.
895///
896/// `Nested`s are constructed using the [`PacketBuilder::wrap_body`] and
897/// [`Serializer::wrap_in`] methods.
898///
899/// When `I: Serializer` and `O: PacketBuilder`, `Nested<I, O>` implements
900/// [`Serializer`].
901#[derive(Copy, Clone, Debug, Eq, PartialEq)]
902pub struct Nested<I, O> {
903    inner: I,
904    outer: O,
905}
906
907impl<I, O> Nested<I, O> {
908    /// Consumes this `Nested` and returns the inner object, discarding the
909    /// outer one.
910    #[inline]
911    pub fn into_inner(self) -> I {
912        self.inner
913    }
914
915    /// Consumes this `Nested` and returns the outer object, discarding the
916    /// inner one.
917    #[inline]
918    pub fn into_outer(self) -> O {
919        self.outer
920    }
921
922    #[inline]
923    pub fn inner(&self) -> &I {
924        &self.inner
925    }
926
927    #[inline]
928    pub fn inner_mut(&mut self) -> &mut I {
929        &mut self.inner
930    }
931
932    #[inline]
933    pub fn outer(&self) -> &O {
934        &self.outer
935    }
936
937    #[inline]
938    pub fn outer_mut(&mut self) -> &mut O {
939        &mut self.outer
940    }
941}
942
943/// A [`PacketBuilder`] which has no header or footer, but which imposes a
944/// maximum body length constraint.
945///
946/// `LimitedSizePacketBuilder`s are constructed using the
947/// [`Serializer::with_size_limit`] method.
948#[derive(Copy, Clone, Debug)]
949#[cfg_attr(test, derive(Eq, PartialEq))]
950pub struct LimitedSizePacketBuilder {
951    /// The maximum body length.
952    pub limit: usize,
953}
954
955impl NestablePacketBuilder for LimitedSizePacketBuilder {
956    fn constraints(&self) -> PacketConstraints {
957        PacketConstraints::with_max_body_len(self.limit)
958    }
959}
960
961impl<C: SerializationContext> PacketBuilder<C> for LimitedSizePacketBuilder {
962    fn serialize(
963        &self,
964        _context: &mut C,
965        _target: &mut SerializeTarget<'_>,
966        _body: FragmentedBytesMut<'_, '_>,
967    ) {
968    }
969}
970
971/// A builder capable of serializing packets - which do not encapsulate other
972/// packets - into an existing buffer.
973///
974/// An `InnerPacketBuilder` describes a packet, and is capable of serializing
975/// that packet into an existing buffer via the `serialize` method. Unlike the
976/// [`PacketBuilder`] trait, it describes a packet which does not encapsulate
977/// other packets.
978///
979/// # Notable implementations
980///
981/// `InnerPacketBuilder` is implemented for `&[u8]`, `&mut [u8]`, and `Vec<u8>`
982/// by treating the contents of the slice/`Vec` as the contents of the packet to
983/// be serialized.
984pub trait InnerPacketBuilder {
985    /// The number of bytes consumed by this packet.
986    fn bytes_len(&self) -> usize;
987
988    /// Serializes this packet into an existing buffer.
989    ///
990    /// `serialize` is called with a buffer of length `self.bytes_len()`, and is
991    /// responsible for serializing the packet into the buffer.
992    ///
993    /// # Security
994    ///
995    /// All of the bytes of the buffer should be initialized, even if only to
996    /// zero, in order to avoid leaking the contents of packets previously
997    /// stored in the same buffer.
998    ///
999    /// # Panics
1000    ///
1001    /// May panic if `buffer.len() != self.bytes_len()`.
1002    fn serialize(&self, buffer: &mut [u8]);
1003
1004    /// Converts this `InnerPacketBuilder` into a [`Serializer`].
1005    ///
1006    /// `into_serializer` is like [`into_serializer_with`], except that no
1007    /// buffer is provided for reuse in serialization.
1008    ///
1009    /// [`into_serializer_with`]: InnerPacketBuilder::into_serializer_with
1010    #[inline]
1011    fn into_serializer(self) -> InnerSerializer<Self, EmptyBuf>
1012    where
1013        Self: Sized,
1014    {
1015        self.into_serializer_with(EmptyBuf)
1016    }
1017
1018    /// Converts this `InnerPacketBuilder` into a [`Serializer`] with a buffer
1019    /// that can be used for serialization.
1020    ///
1021    /// `into_serializer_with` consumes a buffer and converts `self` into a type
1022    /// which implements `Serialize` by treating it as the innermost body to be
1023    /// contained within any encapsulating [`PacketBuilder`]s. During
1024    /// serialization, `buffer` will be provided to the [`BufferProvider`],
1025    /// allowing it to reuse the buffer for serialization and avoid allocating a
1026    /// new one if possible.
1027    ///
1028    /// `buffer` will have its body shrunk to be zero bytes before the
1029    /// `InnerSerializer` is constructed.
1030    fn into_serializer_with<B: ShrinkBuffer>(self, mut buffer: B) -> InnerSerializer<Self, B>
1031    where
1032        Self: Sized,
1033    {
1034        buffer.shrink_back_to(0);
1035        InnerSerializer { inner: self, buffer }
1036    }
1037}
1038
1039impl<'a, I: InnerPacketBuilder> InnerPacketBuilder for &'a I {
1040    #[inline]
1041    fn bytes_len(&self) -> usize {
1042        I::bytes_len(self)
1043    }
1044    #[inline]
1045    fn serialize(&self, buffer: &mut [u8]) {
1046        I::serialize(self, buffer)
1047    }
1048}
1049impl<'a, I: InnerPacketBuilder> InnerPacketBuilder for &'a mut I {
1050    #[inline]
1051    fn bytes_len(&self) -> usize {
1052        I::bytes_len(self)
1053    }
1054    #[inline]
1055    fn serialize(&self, buffer: &mut [u8]) {
1056        I::serialize(self, buffer)
1057    }
1058}
1059impl<'a> InnerPacketBuilder for &'a [u8] {
1060    #[inline]
1061    fn bytes_len(&self) -> usize {
1062        self.len()
1063    }
1064    #[inline]
1065    fn serialize(&self, buffer: &mut [u8]) {
1066        buffer.copy_from_slice(self);
1067    }
1068}
1069impl<'a> InnerPacketBuilder for &'a mut [u8] {
1070    #[inline]
1071    fn bytes_len(&self) -> usize {
1072        self.len()
1073    }
1074    #[inline]
1075    fn serialize(&self, buffer: &mut [u8]) {
1076        buffer.copy_from_slice(self);
1077    }
1078}
1079impl<'a> InnerPacketBuilder for Vec<u8> {
1080    #[inline]
1081    fn bytes_len(&self) -> usize {
1082        self.len()
1083    }
1084    #[inline]
1085    fn serialize(&self, buffer: &mut [u8]) {
1086        buffer.copy_from_slice(self.as_slice());
1087    }
1088}
1089impl<const N: usize> InnerPacketBuilder for ArrayVec<u8, N> {
1090    fn bytes_len(&self) -> usize {
1091        self.as_slice().bytes_len()
1092    }
1093    fn serialize(&self, buffer: &mut [u8]) {
1094        self.as_slice().serialize(buffer);
1095    }
1096}
1097
1098/// An [`InnerPacketBuilder`] created from any [`B: SplitByteSlice`].
1099///
1100/// `ByteSliceInnerPacketBuilder<B>` implements `InnerPacketBuilder` so long as
1101/// `B: SplitByteSlice`.
1102///
1103/// [`B: SplitByteSlice`]: zerocopy::SplitByteSlice
1104pub struct ByteSliceInnerPacketBuilder<B>(pub B);
1105
1106impl<B: SplitByteSlice> InnerPacketBuilder for ByteSliceInnerPacketBuilder<B> {
1107    fn bytes_len(&self) -> usize {
1108        self.0.deref().bytes_len()
1109    }
1110    fn serialize(&self, buffer: &mut [u8]) {
1111        self.0.deref().serialize(buffer)
1112    }
1113}
1114
1115impl<B: SplitByteSlice> Debug for ByteSliceInnerPacketBuilder<B> {
1116    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1117        write!(f, "ByteSliceInnerPacketBuilder({:?})", self.0.as_ref())
1118    }
1119}
1120
1121/// An error in serializing a packet.
1122///
1123/// `SerializeError` is the type of errors returned from methods on the
1124/// [`Serializer`] trait. The `Alloc` variant indicates that a new buffer could
1125/// not be allocated, while the `SizeLimitExceeded` variant indicates that a
1126/// size limit constraint was exceeded.
1127#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1128pub enum SerializeError<A> {
1129    /// A new buffer could not be allocated.
1130    Alloc(A),
1131    /// The size limit constraint was exceeded.
1132    SizeLimitExceeded,
1133}
1134
1135impl<A> SerializeError<A> {
1136    /// Is this `SerializeError::Alloc`?
1137    #[inline]
1138    pub fn is_alloc(&self) -> bool {
1139        match self {
1140            SerializeError::Alloc(_) => true,
1141            SerializeError::SizeLimitExceeded => false,
1142        }
1143    }
1144
1145    /// Is this `SerializeError::SizeLimitExceeded`?
1146    #[inline]
1147    pub fn is_size_limit_exceeded(&self) -> bool {
1148        match self {
1149            SerializeError::Alloc(_) => false,
1150            SerializeError::SizeLimitExceeded => true,
1151        }
1152    }
1153
1154    /// Maps the [`SerializeError::Alloc`] error type.
1155    pub fn map_alloc<T, F: FnOnce(A) -> T>(self, f: F) -> SerializeError<T> {
1156        match self {
1157            SerializeError::Alloc(a) => SerializeError::Alloc(f(a)),
1158            SerializeError::SizeLimitExceeded => SerializeError::SizeLimitExceeded,
1159        }
1160    }
1161}
1162
1163impl<A> From<A> for SerializeError<A> {
1164    fn from(a: A) -> SerializeError<A> {
1165        SerializeError::Alloc(a)
1166    }
1167}
1168
1169/// The error returned when a buffer is too short to hold a serialized packet,
1170/// and the [`BufferProvider`] is incapable of allocating a new one.
1171///
1172/// `BufferTooShortError` is returned by the [`Serializer`] methods
1173/// [`serialize_no_alloc`] and [`serialize_no_alloc_outer`].
1174///
1175/// [`serialize_no_alloc`]: Serializer::serialize_no_alloc
1176/// [`serialize_no_alloc_outer`]: Serializer::serialize_no_alloc_outer
1177#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1178pub struct BufferTooShortError;
1179
1180/// An object capable of providing buffers which satisfy certain constraints.
1181///
1182/// A `BufferProvider<Input, Output>` is an object which is capable of consuming
1183/// a buffer of type `Input` and, either by reusing it or by allocating a new
1184/// one and copying the input buffer's body into it, producing a buffer of type
1185/// `Output` which meets certain prefix and suffix length constraints.
1186///
1187/// A `BufferProvider` must always be provided when serializing a
1188/// [`Serializer`].
1189///
1190/// Implementors may find the helper function [`try_reuse_buffer`] useful.
1191///
1192/// For clients who don't need the full expressive power of this trait, the
1193/// simpler [`BufferAlloc`] trait is provided. It only defines how to allocate
1194/// new buffers, and two blanket impls of `BufferProvider` are provided for all
1195/// `BufferAlloc` types.
1196pub trait BufferProvider<Input, Output> {
1197    /// The type of errors returned from [`reuse_or_realloc`].
1198    ///
1199    /// [`reuse_or_realloc`]: BufferProvider::reuse_or_realloc
1200    type Error;
1201
1202    /// Attempts to produce an output buffer with the given constraints by
1203    /// allocating a new one.
1204    ///
1205    /// `alloc_no_reuse` produces a new buffer with the following invariants:
1206    /// - The output buffer must have at least `prefix` bytes of prefix
1207    /// - The output buffer must have at least `suffix` bytes of suffix
1208    /// - The output buffer must have a body of length `body` bytes.
1209    ///
1210    /// If these requirements cannot be met, then an error is returned.
1211    fn alloc_no_reuse(
1212        self,
1213        prefix: usize,
1214        body: usize,
1215        suffix: usize,
1216    ) -> Result<Output, Self::Error>;
1217
1218    /// Consumes an input buffer and attempts to produce an output buffer with
1219    /// the given constraints, either by reusing the input buffer or by
1220    /// allocating a new one and copying the body into it.
1221    ///
1222    /// `reuse_or_realloc` consumes a buffer by value, and produces a new buffer
1223    /// with the following invariants:
1224    /// - The output buffer must have at least `prefix` bytes of prefix
1225    /// - The output buffer must have at least `suffix` bytes of suffix
1226    /// - The output buffer must have the same body as the input buffer
1227    ///
1228    /// If these requirements cannot be met, then an error is returned along
1229    /// with the input buffer, which is unmodified.
1230    fn reuse_or_realloc(
1231        self,
1232        buffer: Input,
1233        prefix: usize,
1234        suffix: usize,
1235    ) -> Result<Output, (Self::Error, Input)>;
1236}
1237
1238/// An object capable of allocating new buffers.
1239///
1240/// A `BufferAlloc<Output>` is an object which is capable of allocating new
1241/// buffers of type `Output`.
1242///
1243/// [Two blanket implementations] of [`BufferProvider`] are given for any type
1244/// which implements `BufferAlloc<O>`. One blanket implementation works for any
1245/// input buffer type, `I`, and produces buffers of type `Either<I, O>` as
1246/// output. One blanket implementation works only when the input and output
1247/// buffer types are the same, and produces buffers of that type. See the
1248/// documentation on those impls for more details.
1249///
1250/// The following implementations of `BufferAlloc` are provided:
1251/// - Any `FnOnce(usize) -> Result<O, E>` implements `BufferAlloc<O, Error = E>`
1252/// - `()` implements `BufferAlloc<!, Error = ()>` (an allocator which
1253///   always fails)
1254/// - [`new_buf_vec`] implements `BufferAlloc<Buf<Vec<u8>>, Error = !>` (an
1255///   allocator which infallibly heap-allocates `Vec`s)
1256///
1257/// [Two blanket implementations]: trait.BufferProvider.html#implementors
1258pub trait BufferAlloc<Output> {
1259    /// The type of errors returned from [`alloc`].
1260    ///
1261    /// [`alloc`]: BufferAlloc::alloc
1262    type Error;
1263
1264    /// Attempts to allocate a new buffer of size `len`.
1265    fn alloc(self, len: usize) -> Result<Output, Self::Error>;
1266}
1267
1268impl<O, E, F: FnOnce(usize) -> Result<O, E>> BufferAlloc<O> for F {
1269    type Error = E;
1270
1271    #[inline]
1272    fn alloc(self, len: usize) -> Result<O, E> {
1273        self(len)
1274    }
1275}
1276
1277impl BufferAlloc<!> for () {
1278    type Error = ();
1279
1280    #[inline]
1281    fn alloc(self, _len: usize) -> Result<!, ()> {
1282        Err(())
1283    }
1284}
1285
1286/// Allocates a new `Buf<Vec<u8>>`.
1287///
1288/// `new_buf_vec(len)` is shorthand for `Ok(Buf::new(vec![0; len], ..))`. It
1289/// implements [`BufferAlloc<Buf<Vec<u8>>, Error = !>`], and, thanks to a
1290/// blanket impl, [`BufferProvider<I, Either<I, Buf<Vec<u8>>>, Error = !>`]
1291/// for all `I: BufferMut`, and `BufferProvider<Buf<Vec<u8>>, Buf<Vec<u8>>,
1292/// Error = !>`.
1293///
1294/// [`BufferAlloc<Buf<Vec<u8>>, Error = !>`]: BufferAlloc
1295/// [`BufferProvider<I, Either<I, Buf<Vec<u8>>>, Error = !>`]: BufferProvider
1296pub fn new_buf_vec(len: usize) -> Result<Buf<Vec<u8>>, !> {
1297    Ok(Buf::new(vec![0; len], ..))
1298}
1299
1300/// A variant of [`BufferAlloc`] that allocates buffers with the necessary
1301/// prefix, body, suffix layout.
1302pub trait LayoutBufferAlloc<O> {
1303    /// The type of errors returned from [`layout_alloc`].
1304    ///
1305    /// [`layout_alloc`]: LayoutBufferAlloc::layout_alloc
1306    type Error;
1307
1308    /// Like [`BufferAlloc::layout_alloc`], but the returned buffer has reserved
1309    /// `prefix` and `suffix` bytes around `body`.
1310    fn layout_alloc(self, prefix: usize, body: usize, suffix: usize) -> Result<O, Self::Error>;
1311}
1312
1313impl<O: ShrinkBuffer, E, F: FnOnce(usize) -> Result<O, E>> LayoutBufferAlloc<O> for F {
1314    type Error = E;
1315
1316    #[inline]
1317    fn layout_alloc(self, prefix: usize, body: usize, suffix: usize) -> Result<O, E> {
1318        let mut b = self(prefix + body + suffix)?;
1319        b.shrink_front(prefix);
1320        b.shrink_back(suffix);
1321        Ok(b)
1322    }
1323}
1324
1325impl LayoutBufferAlloc<!> for () {
1326    type Error = ();
1327
1328    #[inline]
1329    fn layout_alloc(self, _prefix: usize, _body: usize, _suffix: usize) -> Result<!, ()> {
1330        Err(())
1331    }
1332}
1333
1334/// Attempts to reuse a buffer for the purposes of implementing
1335/// [`BufferProvider::reuse_or_realloc`].
1336///
1337/// `try_reuse_buffer` attempts to reuse an existing buffer to satisfy the given
1338/// prefix and suffix constraints. If it succeeds, it returns `Ok` containing a
1339/// buffer with the same body as the input, and with at least `prefix` prefix
1340/// bytes and at least `suffix` suffix bytes. Otherwise, it returns `Err`
1341/// containing the original, unmodified input buffer.
1342///
1343/// Concretely, `try_reuse_buffer` has the following behavior:
1344/// - If the prefix and suffix constraints are already met, it returns `Ok` with
1345///   the input unmodified
1346/// - If the prefix and suffix constraints are not yet met, then...
1347///   - If there is enough capacity to meet the constraints and the body is not
1348///     larger than `max_copy_bytes`, the body will be moved within the buffer
1349///     in order to meet the constraints, and it will be returned
1350///   - Otherwise, if there is not enough capacity or the body is larger than
1351///     `max_copy_bytes`, it returns `Err` with the input unmodified
1352///
1353/// `max_copy_bytes` is meant to be an estimate of how many bytes can be copied
1354/// before allocating a new buffer will be cheaper than copying.
1355#[inline]
1356pub fn try_reuse_buffer<B: GrowBufferMut + ShrinkBuffer>(
1357    mut buffer: B,
1358    prefix: usize,
1359    suffix: usize,
1360    max_copy_bytes: usize,
1361) -> Result<B, B> {
1362    let need_prefix = prefix;
1363    let need_suffix = suffix;
1364    let have_prefix = buffer.prefix_len();
1365    let have_body = buffer.len();
1366    let have_suffix = buffer.suffix_len();
1367    let need_capacity = need_prefix + have_body + need_suffix;
1368
1369    if have_prefix >= need_prefix && have_suffix >= need_suffix {
1370        // We already satisfy the prefix and suffix requirements.
1371        Ok(buffer)
1372    } else if buffer.capacity() >= need_capacity && have_body <= max_copy_bytes {
1373        // The buffer is large enough, but the body is currently too far
1374        // forward or too far backwards to satisfy the prefix or suffix
1375        // requirements, so we need to move the body within the buffer.
1376        buffer.reset();
1377
1378        // Copy the original body range to a point starting immediatley
1379        // after `prefix`. This satisfies the `prefix` constraint by
1380        // definition, and satisfies the `suffix` constraint since we know
1381        // that the total buffer capacity is sufficient to hold the total
1382        // length of the prefix, body, and suffix.
1383        buffer.copy_within(have_prefix..(have_prefix + have_body), need_prefix);
1384        buffer.shrink(need_prefix..(need_prefix + have_body));
1385        debug_assert_eq!(buffer.prefix_len(), need_prefix);
1386        debug_assert!(buffer.suffix_len() >= need_suffix);
1387        debug_assert_eq!(buffer.len(), have_body);
1388        Ok(buffer)
1389    } else {
1390        Err(buffer)
1391    }
1392}
1393
1394/// Provides an implementation of [`BufferProvider`] from a [`BufferAlloc`] `A`
1395/// that attempts to reuse the input buffer and falls back to the allocator if
1396/// the input buffer can't be reused.
1397pub struct MaybeReuseBufferProvider<A>(pub A);
1398
1399impl<I: ReusableBuffer, O: ReusableBuffer, A: BufferAlloc<O>> BufferProvider<I, Either<I, O>>
1400    for MaybeReuseBufferProvider<A>
1401{
1402    type Error = A::Error;
1403
1404    fn alloc_no_reuse(
1405        self,
1406        prefix: usize,
1407        body: usize,
1408        suffix: usize,
1409    ) -> Result<Either<I, O>, Self::Error> {
1410        let Self(alloc) = self;
1411        let need_capacity = prefix + body + suffix;
1412        BufferAlloc::alloc(alloc, need_capacity).map(|mut buf| {
1413            buf.shrink(prefix..(prefix + body));
1414            Either::B(buf)
1415        })
1416    }
1417
1418    /// If `buffer` has enough capacity to store `need_prefix + need_suffix +
1419    /// buffer.len()` bytes, then reuse `buffer`. Otherwise, allocate a new
1420    /// buffer using `A`'s [`BufferAlloc`] implementation.
1421    ///
1422    /// If there is enough capacity, but the body is too far forwards or
1423    /// backwards in the buffer to satisfy the prefix and suffix constraints,
1424    /// the body will be moved within the buffer in order to satisfy the
1425    /// constraints. This operation is linear in the length of the body.
1426    #[inline]
1427    fn reuse_or_realloc(
1428        self,
1429        buffer: I,
1430        need_prefix: usize,
1431        need_suffix: usize,
1432    ) -> Result<Either<I, O>, (A::Error, I)> {
1433        // TODO(joshlf): Maybe it's worth coming up with a heuristic for when
1434        // moving the body is likely to be more expensive than allocating
1435        // (rather than just using `usize::MAX`)? This will be tough since we
1436        // don't know anything about the performance of `A::alloc`.
1437        match try_reuse_buffer(buffer, need_prefix, need_suffix, usize::MAX) {
1438            Ok(buffer) => Ok(Either::A(buffer)),
1439            Err(buffer) => {
1440                let have_body = buffer.len();
1441                let mut buf = match BufferProvider::<I, Either<I, O>>::alloc_no_reuse(
1442                    self,
1443                    need_prefix,
1444                    have_body,
1445                    need_suffix,
1446                ) {
1447                    Ok(buf) => buf,
1448                    Err(err) => return Err((err, buffer)),
1449                };
1450
1451                buf.copy_from(&buffer);
1452                debug_assert_eq!(buf.prefix_len(), need_prefix);
1453                debug_assert!(buf.suffix_len() >= need_suffix);
1454                debug_assert_eq!(buf.len(), have_body);
1455                Ok(buf)
1456            }
1457        }
1458    }
1459}
1460
1461impl<B: ReusableBuffer, A: BufferAlloc<B>> BufferProvider<B, B> for MaybeReuseBufferProvider<A> {
1462    type Error = A::Error;
1463
1464    fn alloc_no_reuse(self, prefix: usize, body: usize, suffix: usize) -> Result<B, Self::Error> {
1465        BufferProvider::<B, Either<B, B>>::alloc_no_reuse(self, prefix, body, suffix)
1466            .map(Either::into_inner)
1467    }
1468
1469    /// If `buffer` has enough capacity to store `need_prefix + need_suffix +
1470    /// buffer.len()` bytes, then reuse `buffer`. Otherwise, allocate a new
1471    /// buffer using `A`'s [`BufferAlloc`] implementation.
1472    ///
1473    /// If there is enough capacity, but the body is too far forwards or
1474    /// backwards in the buffer to satisfy the prefix and suffix constraints,
1475    /// the body will be moved within the buffer in order to satisfy the
1476    /// constraints. This operation is linear in the length of the body.
1477    #[inline]
1478    fn reuse_or_realloc(self, buffer: B, prefix: usize, suffix: usize) -> Result<B, (A::Error, B)> {
1479        BufferProvider::<B, Either<B, B>>::reuse_or_realloc(self, buffer, prefix, suffix)
1480            .map(Either::into_inner)
1481    }
1482}
1483
1484/// Provides an implementation of [`BufferProvider`] from a [`BufferAlloc`] `A`
1485/// that never attempts to reuse the input buffer, and always create a new
1486/// buffer from the allocator `A`.
1487pub struct NoReuseBufferProvider<A>(pub A);
1488
1489impl<I: FragmentedBuffer, O: ReusableBuffer, A: BufferAlloc<O>> BufferProvider<I, O>
1490    for NoReuseBufferProvider<A>
1491{
1492    type Error = A::Error;
1493
1494    fn alloc_no_reuse(self, prefix: usize, body: usize, suffix: usize) -> Result<O, A::Error> {
1495        let Self(alloc) = self;
1496        alloc.alloc(prefix + body + suffix).map(|mut b| {
1497            b.shrink(prefix..prefix + body);
1498            b
1499        })
1500    }
1501
1502    fn reuse_or_realloc(self, buffer: I, prefix: usize, suffix: usize) -> Result<O, (A::Error, I)> {
1503        BufferProvider::<I, O>::alloc_no_reuse(self, prefix, buffer.len(), suffix)
1504            .map(|mut b| {
1505                b.copy_from(&buffer);
1506                b
1507            })
1508            .map_err(|e| (e, buffer))
1509    }
1510}
1511
1512/// Context in which packet serialization is performed.
1513pub trait SerializationContext: Sized {
1514    /// The packet-specific state required by this serialization context.
1515    type ContextState: Default;
1516
1517    /// Performs nested serialization within the context of an outer
1518    /// [`PacketBuilder`].
1519    ///
1520    /// The provided `serialize_fn` is expected to serialize the packet body and
1521    /// then the packet header and/or footer, each with the provided context.
1522    ///
1523    /// The implementor is expected to call `serialize_fn` and return the result
1524    /// without modification, but it may update its internal state before and/or
1525    /// after doing so if necessary.
1526    fn serialize_nested<O: PacketBuilder<Self>, R>(
1527        &mut self,
1528        _outer: &O,
1529        constraints: PacketConstraints,
1530        serialize_fn: impl FnOnce(&mut Self, PacketConstraints) -> R,
1531    ) -> R {
1532        serialize_fn(self, constraints)
1533    }
1534}
1535
1536// An empty serialization context.
1537#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1538pub struct NoOpSerializationContext;
1539
1540impl SerializationContext for NoOpSerializationContext {
1541    type ContextState = ();
1542
1543    // No need to override the serialization method; the default implementation
1544    // does what we want.
1545}
1546
1547pub trait Serializer<C: SerializationContext>: NestableSerializer + Sized {
1548    /// The type of buffers returned from serialization methods on this trait.
1549    type Buffer;
1550
1551    /// Serializes this `Serializer`, producing a buffer.
1552    ///
1553    /// As `Serializer`s can be nested using the [`Nested`] type (constructed
1554    /// using [`NestablePacketBuilder::wrap_body`] and
1555    /// [`NestableSerializer::wrap_in`]), the `serialize` method is recursive -
1556    /// calling it on a `Nested` will recurse into the inner `Serializer`, which
1557    /// might itself be a `Nested`, and so on. `Nested` ensures that the
1558    /// serialization `context` is passed down the stack of recursive calls.
1559    /// When the innermost `Serializer` is reached, the contained buffer is
1560    /// passed to the `provider`, allowing it to decide how to produce a buffer
1561    /// which is large enough to fit the entire packet - either by reusing the
1562    /// existing buffer, or by discarding it and allocating a new one.
1563    /// `constraints` specifies [`PacketConstraints`] for the outer parts of the
1564    /// packet (header and footer).
1565    fn serialize<B: GrowBufferMut, P: BufferProvider<Self::Buffer, B>>(
1566        self,
1567        context: &mut C,
1568        constraints: PacketConstraints,
1569        provider: P,
1570    ) -> Result<B, (SerializeError<P::Error>, Self)>;
1571
1572    /// Serializes the data into a new buffer without consuming `self`.
1573    ///
1574    /// Creates a new buffer using `alloc` and serializes the data into that
1575    /// that new buffer. Unlike all other serialize methods,
1576    /// `serialize_new_buf` takes `self` by reference. This allows to use the
1577    /// same `Serializer` to serialize the data more than once.
1578    fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
1579        &self,
1580        context: &mut C,
1581        constraints: PacketConstraints,
1582        alloc: A,
1583    ) -> Result<B, SerializeError<A::Error>>;
1584
1585    /// Serializes this `Serializer`, allocating a [`Buf<Vec<u8>>`] if the
1586    /// contained buffer isn't large enough.
1587    ///
1588    /// `serialize_vec` is like [`serialize`], except that, if the contained
1589    /// buffer isn't large enough to contain the packet, a new `Vec<u8>` is
1590    /// allocated and wrapped in a [`Buf`]. If the buffer is large enough, but
1591    /// the body is too far forwards or backwards to fit the encapsulating
1592    /// headers or footers, the body will be moved within the buffer (this
1593    /// operation's cost is linear in the size of the body).
1594    ///
1595    /// `serialize_vec` is equivalent to calling `serialize` with
1596    /// [`new_buf_vec`] as the [`BufferProvider`].
1597    ///
1598    /// [`Buf<Vec<u8>>`]: Buf
1599    /// [`serialize`]: Serializer::serialize
1600    #[inline]
1601    #[allow(clippy::type_complexity)]
1602    fn serialize_vec(
1603        self,
1604        context: &mut C,
1605        constraints: PacketConstraints,
1606    ) -> Result<Either<Self::Buffer, Buf<Vec<u8>>>, (SerializeError<!>, Self)>
1607    where
1608        Self::Buffer: ReusableBuffer,
1609    {
1610        self.serialize(context, constraints, MaybeReuseBufferProvider(new_buf_vec))
1611    }
1612
1613    /// Serializes this `Serializer`, failing if the existing buffer is not
1614    /// large enough.
1615    ///
1616    /// `serialize_no_alloc` is like [`serialize`], except that it will fail if
1617    /// the existing buffer isn't large enough. If the buffer is large enough,
1618    /// but the body is too far forwards or backwards to fit the encapsulating
1619    /// headers or footers, the body will be moved within the buffer (this
1620    /// operation's cost is linear in the size of the body).
1621    ///
1622    /// `serialize_no_alloc` is equivalent to calling `serialize` with a
1623    /// `BufferProvider` which cannot allocate a new buffer (such as `()`).
1624    ///
1625    /// [`serialize`]: Serializer::serialize
1626    #[inline]
1627    fn serialize_no_alloc(
1628        self,
1629        context: &mut C,
1630        constraints: PacketConstraints,
1631    ) -> Result<Self::Buffer, (SerializeError<BufferTooShortError>, Self)>
1632    where
1633        Self::Buffer: ReusableBuffer,
1634    {
1635        self.serialize(context, constraints, MaybeReuseBufferProvider(()))
1636            .map(Either::into_a)
1637            .map_err(|(err, slf)| {
1638                (
1639                    match err {
1640                        SerializeError::Alloc(()) => BufferTooShortError.into(),
1641                        SerializeError::SizeLimitExceeded => SerializeError::SizeLimitExceeded,
1642                    },
1643                    slf,
1644                )
1645            })
1646    }
1647
1648    /// Serializes this `Serializer` as the outermost packet.
1649    ///
1650    /// `serialize_outer` is like [`serialize`], except that it is called when
1651    /// this `Serializer` describes the outermost packet, not encapsulated in
1652    /// any other packets. It is equivalent to calling `serialize` with an empty
1653    /// [`PacketBuilder`] (such as `()`).
1654    ///
1655    /// [`serialize`]: Serializer::serialize
1656    #[inline]
1657    fn serialize_outer<B: GrowBufferMut, P: BufferProvider<Self::Buffer, B>>(
1658        self,
1659        context: &mut C,
1660        provider: P,
1661    ) -> Result<B, (SerializeError<P::Error>, Self)> {
1662        self.serialize(context, PacketConstraints::UNCONSTRAINED, provider)
1663    }
1664
1665    /// Serializes this `Serializer` as the outermost packet, allocating a
1666    /// [`Buf<Vec<u8>>`] if the contained buffer isn't large enough.
1667    ///
1668    /// `serialize_vec_outer` is like [`serialize_vec`], except that it is
1669    /// called when this `Serializer` describes the outermost packet, not
1670    /// encapsulated in any other packets. It is equivalent to calling
1671    /// `serialize_vec` with an empty [`PacketBuilder`] (such as `()`).
1672    ///
1673    /// [`Buf<Vec<u8>>`]: Buf
1674    /// [`serialize_vec`]: Serializer::serialize_vec
1675    #[inline]
1676    #[allow(clippy::type_complexity)]
1677    fn serialize_vec_outer(
1678        self,
1679        context: &mut C,
1680    ) -> Result<Either<Self::Buffer, Buf<Vec<u8>>>, (SerializeError<!>, Self)>
1681    where
1682        Self::Buffer: ReusableBuffer,
1683    {
1684        self.serialize_vec(context, PacketConstraints::UNCONSTRAINED)
1685    }
1686
1687    /// Serializes this `Serializer` as the outermost packet, failing if the
1688    /// existing buffer is not large enough.
1689    ///
1690    /// `serialize_no_alloc_outer` is like [`serialize_no_alloc`], except that
1691    /// it is called when this `Serializer` describes the outermost packet, not
1692    /// encapsulated in any other packets. It is equivalent to calling
1693    /// `serialize_no_alloc` with an empty [`PacketBuilder`] (such as `()`).
1694    ///
1695    /// [`serialize_no_alloc`]: Serializer::serialize_no_alloc
1696    #[inline]
1697    fn serialize_no_alloc_outer(
1698        self,
1699        context: &mut C,
1700    ) -> Result<Self::Buffer, (SerializeError<BufferTooShortError>, Self)>
1701    where
1702        Self::Buffer: ReusableBuffer,
1703    {
1704        self.serialize_no_alloc(context, PacketConstraints::UNCONSTRAINED)
1705    }
1706
1707    /// Like [`Serializer::serialize_vec_outer`], but never attempts to reuse
1708    /// the underlying buffer.
1709    #[inline]
1710    fn serialize_vec_outer_no_reuse(
1711        &self,
1712        context: &mut C,
1713    ) -> Result<Buf<Vec<u8>>, SerializeError<!>> {
1714        self.serialize_new_buf(context, PacketConstraints::UNCONSTRAINED, new_buf_vec)
1715    }
1716}
1717
1718/// Extension trait for `Serializer` that allows for composition of serializers
1719/// without type hints by deferring the resolution of the concrete serialization
1720/// context type.
1721pub trait NestableSerializer: Sized {
1722    /// Encapsulates this `Serializer` in a packet, producing a new
1723    /// `Serializer`.
1724    ///
1725    /// `wrap_in()` consumes this `Serializer` and a [`PacketBuilder`], and
1726    /// produces a new `Serializer` which describes encapsulating this one in
1727    /// the packet described by `outer`.
1728    #[inline]
1729    fn wrap_in<B: NestablePacketBuilder>(self, outer: B) -> Nested<Self, B> {
1730        outer.wrap_body(self)
1731    }
1732
1733    /// Creates a new `Serializer` which will enforce a size limit.
1734    ///
1735    /// `with_size_limit` consumes this `Serializer` and limit, and produces a
1736    /// new `Serializer` which will enforce the given limit on all serialization
1737    /// requests. Note that the given limit will be enforced at this layer -
1738    /// serialization requests will be rejected if the body produced by the
1739    /// request at this layer would exceed the limit. It has no effect on
1740    /// headers or footers added by encapsulating layers outside of this one.
1741    #[inline]
1742    fn with_size_limit(self, limit: usize) -> Nested<Self, LimitedSizePacketBuilder> {
1743        self.wrap_in(LimitedSizePacketBuilder { limit })
1744    }
1745}
1746
1747/// A [`Serializer`] constructed from an [`InnerPacketBuilder`].
1748///
1749/// An `InnerSerializer` wraps an `InnerPacketBuilder` and a buffer, and
1750/// implements the `Serializer` trait. When a serialization is requested, it
1751/// either reuses the stored buffer or allocates a new one large enough to hold
1752/// itself and all outer `PacketBuilder`s.
1753#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1754pub struct InnerSerializer<I, B> {
1755    inner: I,
1756    // The buffer's length must be zero since we encapsulate the buffer in a
1757    // PacketBuilder. If the length were non-zero, that would have the effect of
1758    // retaining the contents of the buffer when serializing, and putting them
1759    // immediately after the bytes of `inner`.
1760    buffer: B,
1761}
1762
1763impl<I, B> InnerSerializer<I, B> {
1764    pub fn inner(&self) -> &I {
1765        &self.inner
1766    }
1767}
1768
1769/// A wrapper for `InnerPacketBuilders` which implements `PacketBuilder` by
1770/// treating the entire `InnerPacketBuilder` as the header of the
1771/// `PacketBuilder`. This allows us to compose our InnerPacketBuilder with
1772/// the outer `PacketBuilders` into a single, large `PacketBuilder`, and then
1773/// serialize it using `self.buffer`.
1774struct InnerPacketBuilderWrapper<I>(I);
1775
1776impl<I: InnerPacketBuilder> NestablePacketBuilder for InnerPacketBuilderWrapper<I> {
1777    fn constraints(&self) -> PacketConstraints {
1778        let Self(wrapped) = self;
1779        PacketConstraints::new(wrapped.bytes_len(), 0, 0, usize::MAX)
1780    }
1781}
1782
1783impl<C: SerializationContext, I: InnerPacketBuilder> PacketBuilder<C>
1784    for InnerPacketBuilderWrapper<I>
1785{
1786    fn serialize(
1787        &self,
1788        _context: &mut C,
1789        target: &mut SerializeTarget<'_>,
1790        _body: FragmentedBytesMut<'_, '_>,
1791    ) {
1792        let Self(wrapped) = self;
1793
1794        // Note that the body might be non-empty if an outer
1795        // PacketBuilder added a minimum body length constraint that
1796        // required padding.
1797        debug_assert_eq!(target.header.len(), wrapped.bytes_len());
1798        debug_assert_eq!(target.footer.len(), 0);
1799
1800        InnerPacketBuilder::serialize(wrapped, target.header);
1801    }
1802}
1803
1804impl<C: SerializationContext, I: InnerPacketBuilder, B: GrowBuffer + ShrinkBuffer> Serializer<C>
1805    for InnerSerializer<I, B>
1806{
1807    type Buffer = B;
1808
1809    #[inline]
1810    fn serialize<BB: GrowBufferMut, P: BufferProvider<B, BB>>(
1811        self,
1812        context: &mut C,
1813        constraints: PacketConstraints,
1814        provider: P,
1815    ) -> Result<BB, (SerializeError<P::Error>, InnerSerializer<I, B>)> {
1816        debug_assert_eq!(self.buffer.len(), 0);
1817        InnerPacketBuilderWrapper(self.inner)
1818            .wrap_body(self.buffer)
1819            .serialize(context, constraints, provider)
1820            .map_err(|(err, Nested { inner: buffer, outer: pb })| {
1821                (err, InnerSerializer { inner: pb.0, buffer })
1822            })
1823    }
1824
1825    #[inline]
1826    fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
1827        &self,
1828        context: &mut C,
1829        outer: PacketConstraints,
1830        alloc: A,
1831    ) -> Result<BB, SerializeError<A::Error>> {
1832        InnerPacketBuilderWrapper(&self.inner)
1833            .wrap_body(EmptyBuf)
1834            .serialize_new_buf(context, outer, alloc)
1835    }
1836}
1837
1838impl<I: InnerPacketBuilder, B: GrowBuffer + ShrinkBuffer> NestableSerializer
1839    for InnerSerializer<I, B>
1840{
1841}
1842
1843impl<C: SerializationContext, B: GrowBuffer + ShrinkBuffer> Serializer<C> for B {
1844    type Buffer = B;
1845
1846    #[inline]
1847    fn serialize<BB: GrowBufferMut, P: BufferProvider<Self::Buffer, BB>>(
1848        self,
1849        context: &mut C,
1850        constraints: PacketConstraints,
1851        provider: P,
1852    ) -> Result<BB, (SerializeError<P::Error>, Self)> {
1853        TruncatingSerializer::new(self, TruncateDirection::NoTruncating)
1854            .serialize(context, constraints, provider)
1855            .map_err(|(err, ser)| (err, ser.buffer))
1856    }
1857
1858    fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
1859        &self,
1860        _context: &mut C,
1861        constraints: PacketConstraints,
1862        alloc: A,
1863    ) -> Result<BB, SerializeError<A::Error>> {
1864        if self.len() > constraints.max_body_len() {
1865            return Err(SerializeError::SizeLimitExceeded);
1866        }
1867
1868        let padding = constraints.min_body_len().saturating_sub(self.len());
1869        let tail_size = padding + constraints.footer_len();
1870        let mut buffer = alloc.layout_alloc(constraints.header_len(), self.len(), tail_size)?;
1871        buffer.copy_from(self);
1872        buffer.grow_back_zero(padding);
1873        Ok(buffer)
1874    }
1875}
1876
1877impl<B: GrowBuffer + ShrinkBuffer> NestableSerializer for B {}
1878
1879/// Either of two serializers.
1880///
1881/// An `EitherSerializer` wraps one of two different serializer types.
1882pub enum EitherSerializer<A, B> {
1883    A(A),
1884    B(B),
1885}
1886
1887impl<C: SerializationContext, A: Serializer<C>, B: Serializer<C, Buffer = A::Buffer>> Serializer<C>
1888    for EitherSerializer<A, B>
1889{
1890    type Buffer = A::Buffer;
1891
1892    fn serialize<TB: GrowBufferMut, P: BufferProvider<Self::Buffer, TB>>(
1893        self,
1894        context: &mut C,
1895        constraints: PacketConstraints,
1896        provider: P,
1897    ) -> Result<TB, (SerializeError<P::Error>, Self)> {
1898        match self {
1899            EitherSerializer::A(s) => s
1900                .serialize(context, constraints, provider)
1901                .map_err(|(err, s)| (err, EitherSerializer::A(s))),
1902            EitherSerializer::B(s) => s
1903                .serialize(context, constraints, provider)
1904                .map_err(|(err, s)| (err, EitherSerializer::B(s))),
1905        }
1906    }
1907
1908    fn serialize_new_buf<TB: GrowBufferMut, BA: LayoutBufferAlloc<TB>>(
1909        &self,
1910        context: &mut C,
1911        outer: PacketConstraints,
1912        alloc: BA,
1913    ) -> Result<TB, SerializeError<BA::Error>> {
1914        match self {
1915            EitherSerializer::A(s) => s.serialize_new_buf(context, outer, alloc),
1916            EitherSerializer::B(s) => s.serialize_new_buf(context, outer, alloc),
1917        }
1918    }
1919}
1920
1921impl<A: NestableSerializer, B: NestableSerializer> NestableSerializer for EitherSerializer<A, B> {}
1922
1923/// The direction a buffer's body should be truncated from to force
1924/// it to fit within a size limit.
1925#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1926pub enum TruncateDirection {
1927    /// If a buffer cannot fit within a limit, discard bytes from the
1928    /// front of the body.
1929    DiscardFront,
1930    /// If a buffer cannot fit within a limit, discard bytes from the
1931    /// end of the body.
1932    DiscardBack,
1933    /// Do not attempt to truncate a buffer to make it fit within a limit.
1934    NoTruncating,
1935}
1936
1937/// A [`Serializer`] that truncates its body if it would exceed a size limit.
1938///
1939/// `TruncatingSerializer` wraps a buffer, and implements `Serializer`. Unlike
1940/// the blanket impl of `Serializer` for `B: GrowBuffer + ShrinkBuffer`, if the
1941/// buffer's body exceeds the size limit constraint passed to
1942/// `Serializer::serialize`, the body is truncated to fit.
1943///
1944/// Note that this does not guarantee that size limit exceeded errors will not
1945/// occur. The size limit may be small enough that the encapsulating headers
1946/// alone exceed the size limit.  There may also be a minimum body length
1947/// constraint which is larger than the size limit.
1948#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1949pub struct TruncatingSerializer<B> {
1950    buffer: B,
1951    direction: TruncateDirection,
1952}
1953
1954impl<B> TruncatingSerializer<B> {
1955    /// Constructs a new `TruncatingSerializer`.
1956    pub fn new(buffer: B, direction: TruncateDirection) -> TruncatingSerializer<B> {
1957        TruncatingSerializer { buffer, direction }
1958    }
1959
1960    /// Provides shared access to the inner buffer.
1961    pub fn buffer(&self) -> &B {
1962        &self.buffer
1963    }
1964
1965    /// Provides mutable access to the inner buffer.
1966    pub fn buffer_mut(&mut self) -> &mut B {
1967        &mut self.buffer
1968    }
1969}
1970
1971impl<C: SerializationContext, B: GrowBuffer + ShrinkBuffer> Serializer<C>
1972    for TruncatingSerializer<B>
1973{
1974    type Buffer = B;
1975
1976    fn serialize<BB: GrowBufferMut, P: BufferProvider<B, BB>>(
1977        mut self,
1978        _context: &mut C,
1979        constraints: PacketConstraints,
1980        provider: P,
1981    ) -> Result<BB, (SerializeError<P::Error>, Self)> {
1982        let original_len = self.buffer.len();
1983        let excess_bytes = if original_len > constraints.max_body_len() {
1984            Some(original_len - constraints.max_body_len())
1985        } else {
1986            None
1987        };
1988        if let Some(excess_bytes) = excess_bytes {
1989            match self.direction {
1990                TruncateDirection::DiscardFront => self.buffer.shrink_front(excess_bytes),
1991                TruncateDirection::DiscardBack => self.buffer.shrink_back(excess_bytes),
1992                TruncateDirection::NoTruncating => {
1993                    return Err((SerializeError::SizeLimitExceeded, self));
1994                }
1995            }
1996        }
1997
1998        let padding = constraints.min_body_len().saturating_sub(self.buffer.len());
1999
2000        // At this point, the body and padding MUST fit within the limit. Note
2001        // that PacketConstraints guarantees that min_body_len <= max_body_len,
2002        // so the padding can't cause this assertion to fail.
2003        debug_assert!(self.buffer.len() + padding <= constraints.max_body_len());
2004        match provider.reuse_or_realloc(
2005            self.buffer,
2006            constraints.header_len(),
2007            padding + constraints.footer_len(),
2008        ) {
2009            Ok(buffer) => Ok(buffer),
2010            Err((err, mut buffer)) => {
2011                // Undo the effects of shrinking the buffer so that the buffer
2012                // we return is unmodified from its original (which is required
2013                // by the contract of this method).
2014                if let Some(excess_bytes) = excess_bytes {
2015                    match self.direction {
2016                        TruncateDirection::DiscardFront => buffer.grow_front(excess_bytes),
2017                        TruncateDirection::DiscardBack => buffer.grow_back(excess_bytes),
2018                        TruncateDirection::NoTruncating => unreachable!(),
2019                    }
2020                }
2021
2022                Err((
2023                    SerializeError::Alloc(err),
2024                    TruncatingSerializer { buffer, direction: self.direction },
2025                ))
2026            }
2027        }
2028    }
2029
2030    fn serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2031        &self,
2032        _context: &mut C,
2033        outer: PacketConstraints,
2034        alloc: A,
2035    ) -> Result<BB, SerializeError<A::Error>> {
2036        let truncated_size = cmp::min(self.buffer.len(), outer.max_body_len());
2037        let discarded_bytes = self.buffer.len() - truncated_size;
2038        let padding = outer.min_body_len().saturating_sub(truncated_size);
2039        let tail_size = padding + outer.footer_len();
2040        let mut buffer = alloc.layout_alloc(outer.header_len(), truncated_size, tail_size)?;
2041        buffer.with_bytes_mut(|mut dst| {
2042            self.buffer.with_bytes(|src| {
2043                let src = match (discarded_bytes > 0, self.direction) {
2044                    (false, _) => src,
2045                    (true, TruncateDirection::DiscardFront) => src.slice(discarded_bytes..),
2046                    (true, TruncateDirection::DiscardBack) => src.slice(..truncated_size),
2047                    (true, TruncateDirection::NoTruncating) => {
2048                        return Err(SerializeError::SizeLimitExceeded);
2049                    }
2050                };
2051                dst.copy_from(&src);
2052                Ok(())
2053            })
2054        })?;
2055        buffer.grow_back_zero(padding);
2056        Ok(buffer)
2057    }
2058}
2059
2060impl<B: GrowBuffer + ShrinkBuffer> NestableSerializer for TruncatingSerializer<B> {}
2061
2062impl<C: SerializationContext, I: Serializer<C>, O: PacketBuilder<C>> Serializer<C>
2063    for Nested<I, O>
2064{
2065    type Buffer = I::Buffer;
2066
2067    #[inline]
2068    fn serialize<B: GrowBufferMut, P: BufferProvider<I::Buffer, B>>(
2069        self,
2070        context: &mut C,
2071        constraints: PacketConstraints,
2072        provider: P,
2073    ) -> Result<B, (SerializeError<P::Error>, Self)> {
2074        context
2075            .serialize_nested(&self.outer, constraints, |context, constraints| {
2076                let Some(constraints) = self.outer.constraints().try_encapsulate(&constraints)
2077                else {
2078                    return Err((SerializeError::SizeLimitExceeded, self.inner));
2079                };
2080                self.inner.serialize(context, constraints, provider).map(|mut buf| {
2081                    buf.serialize(context, &self.outer);
2082                    buf
2083                })
2084            })
2085            .map_err(|(err, inner)| (err, self.outer.wrap_body(inner)))
2086    }
2087
2088    #[inline]
2089    fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2090        &self,
2091        context: &mut C,
2092        constraints: PacketConstraints,
2093        alloc: A,
2094    ) -> Result<B, SerializeError<A::Error>> {
2095        context.serialize_nested(&self.outer, constraints, |context, constraints| {
2096            let Some(constraints) = self.outer.constraints().try_encapsulate(&constraints) else {
2097                return Err(SerializeError::SizeLimitExceeded);
2098            };
2099            self.inner.serialize_new_buf(context, constraints, alloc).map(|mut buf| {
2100                buf.serialize(context, &self.outer);
2101                buf
2102            })
2103        })
2104    }
2105}
2106
2107impl<I: NestableSerializer, O: NestablePacketBuilder> NestableSerializer for Nested<I, O> {}
2108
2109/// A packet builder used for partial packet serialization.
2110pub trait PartialPacketBuilder<C: SerializationContext>: PacketBuilder<C> {
2111    /// Serializes the header to the specified `buffer`.
2112    ///
2113    /// Checksums (if any) should not calculated. The corresponding fields
2114    /// should be set to 0.
2115    ///
2116    /// `body_len` specifies size of the packet body wrapped by this
2117    /// `PacketBuilder`. It is supplied so the correct packet size can be
2118    /// written in the header.
2119    fn partial_serialize(&self, context: &mut C, body_len: usize, buffer: &mut [u8]);
2120}
2121
2122impl<C: SerializationContext> PartialPacketBuilder<C> for () {
2123    fn partial_serialize(&self, _context: &mut C, _body_len: usize, _buffer: &mut [u8]) {}
2124}
2125
2126/// Result returned by `PartialSerializer::partial_serialize`.
2127#[derive(Debug, Eq, PartialEq)]
2128pub enum PartialSerializeResult<'a, B> {
2129    Slice(&'a [u8]),
2130    NewBuffer { buffer: B, total_size: usize },
2131}
2132
2133/// A serializer that supports partial serialization.
2134///
2135/// Partial serialization allows to serialize only packet headers without
2136/// calculating packet checksums (if any).
2137pub trait PartialSerializer<C: SerializationContext> {
2138    /// If the packet is already serialized then returns the whole seialized
2139    /// packet as `PartialSerializeResult::Slice`. Otherwise serializes the
2140    /// headers into a new buffer returned as `PartialSerializeResult::NewBuffer`.
2141    fn partial_serialize<B: GrowBufferMut + ContiguousBuffer, A: LayoutBufferAlloc<B>>(
2142        &self,
2143        context: &mut C,
2144        alloc: A,
2145    ) -> Result<PartialSerializeResult<'_, B>, SerializeError<A::Error>> {
2146        let (buffer, total_size) =
2147            self.partial_serialize_new_buf(context, PacketConstraints::UNCONSTRAINED, alloc)?;
2148        Ok(PartialSerializeResult::NewBuffer { buffer, total_size })
2149    }
2150
2151    /// Serializes the headers into a new buffer allocated used `alloc`.
2152    ///
2153    /// Returns a buffer with serialized headers. If the serializer doesn't
2154    /// serialize any headers then an empty buffer is returned. In either case,
2155    /// the buffer is guaranteed to contain exactly `constraints.header_len()`
2156    /// at the head.
2157    ///
2158    /// The second returned value indicates total number of bytes in the
2159    /// packet, including the headers.
2160    fn partial_serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2161        &self,
2162        context: &mut C,
2163        constraints: PacketConstraints,
2164        alloc: A,
2165    ) -> Result<(B, usize), SerializeError<A::Error>>;
2166}
2167
2168impl<C, B> PartialSerializer<C> for B
2169where
2170    C: SerializationContext,
2171    B: GrowBuffer + ShrinkBuffer,
2172{
2173    fn partial_serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2174        &self,
2175        _context: &mut C,
2176        constraints: PacketConstraints,
2177        alloc: A,
2178    ) -> Result<(BB, usize), SerializeError<A::Error>> {
2179        let buffer = alloc.layout_alloc(constraints.header_len(), 0, 0)?;
2180        Ok((buffer, self.len()))
2181    }
2182}
2183
2184impl<C, B> PartialSerializer<C> for TruncatingSerializer<B>
2185where
2186    C: SerializationContext,
2187    B: GrowBuffer + ShrinkBuffer,
2188{
2189    fn partial_serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2190        &self,
2191        _context: &mut C,
2192        constraints: PacketConstraints,
2193        alloc: A,
2194    ) -> Result<(BB, usize), SerializeError<A::Error>> {
2195        let total_size = cmp::max(
2196            constraints.min_body_len(),
2197            cmp::min(self.buffer().len(), constraints.max_body_len()),
2198        );
2199        let buffer = alloc.layout_alloc(constraints.header_len(), 0, 0)?;
2200        Ok((buffer, total_size))
2201    }
2202}
2203
2204impl<C, I, B> PartialSerializer<C> for InnerSerializer<I, B>
2205where
2206    C: SerializationContext,
2207    I: InnerPacketBuilder,
2208    B: GrowBuffer + ShrinkBuffer,
2209{
2210    fn partial_serialize_new_buf<BB: GrowBufferMut, A: LayoutBufferAlloc<BB>>(
2211        &self,
2212        _context: &mut C,
2213        constraints: PacketConstraints,
2214        alloc: A,
2215    ) -> Result<(BB, usize), SerializeError<A::Error>> {
2216        let total_size = cmp::max(self.inner().bytes_len(), constraints.min_body_len());
2217        let buffer = alloc.layout_alloc(constraints.header_len(), 0, 0)?;
2218        Ok((buffer, total_size))
2219    }
2220}
2221
2222impl<C, A, B> PartialSerializer<C> for EitherSerializer<A, B>
2223where
2224    C: SerializationContext,
2225    A: PartialSerializer<C>,
2226    B: PartialSerializer<C>,
2227{
2228    fn partial_serialize_new_buf<BB: GrowBufferMut, AA: LayoutBufferAlloc<BB>>(
2229        &self,
2230        context: &mut C,
2231        constraints: PacketConstraints,
2232        alloc: AA,
2233    ) -> Result<(BB, usize), SerializeError<AA::Error>> {
2234        match self {
2235            EitherSerializer::A(s) => s.partial_serialize_new_buf(context, constraints, alloc),
2236            EitherSerializer::B(s) => s.partial_serialize_new_buf(context, constraints, alloc),
2237        }
2238    }
2239}
2240
2241impl<C, I, O> PartialSerializer<C> for Nested<I, O>
2242where
2243    C: SerializationContext,
2244    I: PartialSerializer<C>,
2245    O: PartialPacketBuilder<C>,
2246{
2247    fn partial_serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2248        &self,
2249        context: &mut C,
2250        constraints: PacketConstraints,
2251        alloc: A,
2252    ) -> Result<(B, usize), SerializeError<A::Error>> {
2253        context.serialize_nested(&self.outer, constraints, |context, constraints| {
2254            let header_constraints = self.outer.constraints();
2255            let Some(constraints) = header_constraints.try_encapsulate(&constraints) else {
2256                return Err(SerializeError::SizeLimitExceeded);
2257            };
2258            let header_len = header_constraints.header_len();
2259            let (mut buffer, mut total_size) =
2260                self.inner.partial_serialize_new_buf(context, constraints, alloc)?;
2261            buffer.with_parts_mut(|prefix, _body, _suffix| {
2262                let header_offset = prefix.len() - header_len;
2263                let header = &mut prefix[header_offset..];
2264                self.outer.partial_serialize(context, total_size, header);
2265            });
2266            buffer.grow_front(header_len);
2267            total_size += header_len + header_constraints.footer_len();
2268            Ok((buffer, total_size))
2269        })
2270    }
2271}
2272
2273mod sealed {
2274    use super::*;
2275
2276    /// The inner workings of [`DynamicSerializer`].
2277    ///
2278    /// This trait is sealed because we don't want it to be implementable
2279    /// outside this crate or for its methods to be callable.
2280    pub trait DynamicSerializerInner<C: SerializationContext> {
2281        /// Serializes this serializer using a dyn borrow to an allocator.
2282        ///
2283        /// This method behaves much like [`Serializer::serialize_new_buf`], but
2284        /// with a specific shape allowing for dynamic dispatch.
2285        ///
2286        /// The target buffer is allocated via [`DynamicBufferAlloc`] and,
2287        /// instead of returning an owned buffer, it returns the total number of
2288        /// bytes in `prefix`, `suffix` that the buffer taken from the allocator
2289        /// _must have_ after having serialized this entity.
2290        fn serialize_dyn_alloc(
2291            &self,
2292            context: &mut C,
2293            outer: PacketConstraints,
2294            alloc: &mut dyn DynamicBufferAlloc,
2295        ) -> Result<(usize, usize), SerializeError<DynAllocError>>;
2296    }
2297
2298    pub trait DynamicPartialSerializerInner<C: SerializationContext> {
2299        fn partial_serialize_dyn_alloc(
2300            &self,
2301            context: &mut C,
2302            constraints: PacketConstraints,
2303            alloc: &mut dyn DynamicBufferAlloc,
2304        ) -> Result<usize, SerializeError<DynAllocError>>;
2305    }
2306
2307    /// Type-erased allocator allowing dynamic serializers through
2308    /// [`DynamicSerializerInner`].
2309    ///
2310    /// This has roughly the same shape as [`LayoutBufferAlloc`], but with
2311    /// dynamic dispatch capabilities.
2312    pub trait DynamicBufferAlloc {
2313        /// Allocates a buffer with `prefix`, `body`, `suffix` bytes, like
2314        /// [`LayoutBufferAlloc::layout_alloc`].
2315        ///
2316        /// Note that the returned buffer has a tied lifetime to the allocator.
2317        /// The type erasure here is achieved by storing the buffer within the
2318        /// allocator itself, which can then be extracted to fulfill the
2319        /// `Serializer` trait. See the `Adapter` implementations supporting
2320        /// [`DynamicSerializerInner`] for details.
2321        ///
2322        /// This trait is sealed because we don't want it to be implementable
2323        /// outside this crate or for its methods to be callable.
2324        ///
2325        /// `alloc` may only be called once per instance of
2326        /// `DynamicBufferAlloc`. It reflects the single-use nature of
2327        /// [`LayoutBufferAlloc`], but methods taking `self` is not dyn
2328        /// compatible. Implementors may panic if called more than once on the
2329        /// same instance.
2330        fn alloc(
2331            &mut self,
2332            prefix: usize,
2333            body: usize,
2334            suffix: usize,
2335        ) -> Result<Buf<&mut [u8]>, DynAllocError>;
2336    }
2337
2338    /// The temporary errors returned by dynamic helpers in
2339    /// [`DynamicSerializerInner`] and [`DynamicBufferAlloc`].
2340    pub struct DynAllocError;
2341}
2342
2343use sealed::{
2344    DynAllocError, DynamicBufferAlloc, DynamicPartialSerializerInner, DynamicSerializerInner,
2345};
2346
2347/// `DynamicBufferAlloc` implementation that wraps an `LayoutBufferAlloc`
2348enum DynBufferAlloc<A: LayoutBufferAlloc<B>, B> {
2349    Empty,
2350    Alloc(A),
2351    Buffer(B),
2352    Error(A::Error),
2353}
2354
2355impl<A: LayoutBufferAlloc<B>, B> DynBufferAlloc<A, B> {
2356    fn take_buffer(self) -> B {
2357        let DynBufferAlloc::Buffer(b) = self else { unreachable!("unexpected alloc state") };
2358        b
2359    }
2360
2361    fn take_error(self) -> A::Error {
2362        let DynBufferAlloc::Error(e) = self else { unreachable!("unexpected alloc state") };
2363        e
2364    }
2365}
2366
2367impl<A: LayoutBufferAlloc<B>, B: GrowBufferMut> DynamicBufferAlloc for DynBufferAlloc<A, B> {
2368    fn alloc(
2369        &mut self,
2370        prefix: usize,
2371        body: usize,
2372        suffix: usize,
2373    ) -> Result<Buf<&mut [u8]>, DynAllocError> {
2374        let alloc = match core::mem::replace(self, Self::Empty) {
2375            Self::Alloc(a) => a,
2376            _ => panic!("unexpected alloc state"),
2377        };
2378
2379        let buffer = match alloc.layout_alloc(prefix, body, suffix) {
2380            Ok(b) => b,
2381            Err(e) => {
2382                *self = Self::Error(e);
2383                return Err(DynAllocError);
2384            }
2385        };
2386        *self = Self::Buffer(buffer);
2387        let buffer = match self {
2388            Self::Buffer(b) => b.with_all_contents_mut(|b| match b.try_into_contiguous() {
2389                Ok(b) => b,
2390                Err(_) => {
2391                    todo!("https://fxbug.dev/428952155: support dyn serialize fragmented buffers")
2392                }
2393            }),
2394            // We just set buffer above.
2395            _ => unreachable!(),
2396        };
2397        Ok(Buf::new(buffer, prefix..(buffer.len() - suffix)))
2398    }
2399}
2400
2401fn dyn_serialize_new_buf<C: SerializationContext, B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2402    serializer: &dyn DynamicSerializerInner<C>,
2403    context: &mut C,
2404    outer: PacketConstraints,
2405    alloc: A,
2406) -> Result<B, SerializeError<A::Error>> {
2407    let mut alloc = DynBufferAlloc::Alloc(alloc);
2408    let (prefix, suffix) = match serializer.serialize_dyn_alloc(context, outer, &mut alloc) {
2409        Ok(result) => result,
2410        Err(SerializeError::SizeLimitExceeded) => return Err(SerializeError::SizeLimitExceeded),
2411        Err(SerializeError::Alloc(DynAllocError)) => {
2412            return Err(SerializeError::Alloc(alloc.take_error()));
2413        }
2414    };
2415
2416    let mut buffer = alloc.take_buffer();
2417    buffer.grow_front(buffer.prefix_len().checked_sub(prefix).unwrap_or_else(|| {
2418        panic!("failed to grow buffer front; want: {} got: {}", prefix, buffer.prefix_len())
2419    }));
2420    buffer.grow_back(buffer.suffix_len().checked_sub(suffix).unwrap_or_else(|| {
2421        panic!("failed to grow buffer back; want: {} got: {}", suffix, buffer.suffix_len())
2422    }));
2423    Ok(buffer)
2424}
2425
2426/// A type that provides [`Serializer`] via dynamic dispatch.
2427///
2428/// See discussion on [`DynamicSerializer`] for when dynamically dispatched
2429/// serializers can be beneficial.
2430#[derive(Copy, Clone)]
2431pub struct DynSerializer<'a, C: SerializationContext>(&'a dyn DynamicSerializerInner<C>);
2432
2433impl<'a, C: SerializationContext> DynSerializer<'a, C> {
2434    /// Creates a new `DynSerializer` from a borrow to a concrete serializer.
2435    pub fn new<S: Serializer<C>>(s: &'a S) -> Self {
2436        Self::new_dyn(s)
2437    }
2438
2439    /// Creates a new `DynSerializer` from a fat `DynamicSerializer` pointer.
2440    pub fn new_dyn(s: &'a dyn DynamicSerializer<C>) -> Self {
2441        Self(s)
2442    }
2443}
2444
2445impl<C: SerializationContext> Serializer<C> for DynSerializer<'_, C> {
2446    type Buffer = EmptyBuf;
2447
2448    fn serialize<B: GrowBufferMut, P: BufferProvider<Self::Buffer, B>>(
2449        self,
2450        context: &mut C,
2451        constraints: PacketConstraints,
2452        provider: P,
2453    ) -> Result<B, (SerializeError<P::Error>, Self)> {
2454        struct Adapter<S, P>(P, PhantomData<S>);
2455
2456        impl<S, B, P> LayoutBufferAlloc<B> for Adapter<S, P>
2457        where
2458            P: BufferProvider<S, B>,
2459        {
2460            type Error = P::Error;
2461
2462            fn layout_alloc(
2463                self,
2464                prefix: usize,
2465                body: usize,
2466                suffix: usize,
2467            ) -> Result<B, Self::Error> {
2468                let Self(provider, PhantomData) = self;
2469                provider.alloc_no_reuse(prefix, body, suffix)
2470            }
2471        }
2472
2473        let Self(serializer) = self;
2474        match dyn_serialize_new_buf(
2475            serializer,
2476            context,
2477            constraints,
2478            Adapter(provider, PhantomData),
2479        ) {
2480            Ok(b) => Ok(b),
2481            Err(e) => Err((e, self)),
2482        }
2483    }
2484
2485    fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2486        &self,
2487        context: &mut C,
2488        constraints: PacketConstraints,
2489        alloc: A,
2490    ) -> Result<B, SerializeError<A::Error>> {
2491        let Self(serializer) = self;
2492        dyn_serialize_new_buf(*serializer, context, constraints, alloc)
2493    }
2494}
2495
2496// `LayoutBufferAlloc` implementation that wraps a `DynamicBufferAlloc`.
2497struct DynamicBufferAllocAdapter<'a>(&'a mut dyn DynamicBufferAlloc);
2498impl<'a> LayoutBufferAlloc<Buf<&'a mut [u8]>> for DynamicBufferAllocAdapter<'a> {
2499    type Error = DynAllocError;
2500
2501    fn layout_alloc(
2502        self,
2503        prefix: usize,
2504        body: usize,
2505        suffix: usize,
2506    ) -> Result<Buf<&'a mut [u8]>, Self::Error> {
2507        let Self(inner) = self;
2508        inner.alloc(prefix, body, suffix)
2509    }
2510}
2511
2512impl<C: SerializationContext> NestableSerializer for DynSerializer<'_, C> {}
2513
2514impl<C: SerializationContext, O: Serializer<C>> DynamicSerializerInner<C> for O {
2515    fn serialize_dyn_alloc(
2516        &self,
2517        context: &mut C,
2518        outer: PacketConstraints,
2519        alloc: &mut dyn DynamicBufferAlloc,
2520    ) -> Result<(usize, usize), SerializeError<DynAllocError>> {
2521        self.serialize_new_buf(context, outer, DynamicBufferAllocAdapter(alloc))
2522            .map(|buffer| (buffer.prefix_len(), buffer.suffix_len()))
2523    }
2524}
2525
2526/// A marker trait that is used as an attestation of dynamic serialization
2527/// capabilities.
2528///
2529/// Use [`DynSerializer`] to create instances of dynamic serializers.
2530///
2531/// # Discussion
2532///
2533/// If serializers are passed deep down the call stack, causing local
2534/// instantiation of multiple functions, it might be beneficial to consider
2535/// using a dynamically dispatched serializer instead. The hit taken during code
2536/// generation (and compilation times) might not be worth it, depending on the
2537/// task at hand. As an example, slow-path protocols might not derive much
2538/// benefit from deep compiler optimization which tips the scales in favor of
2539/// using a dynamically dispatched serializer instead.
2540pub trait DynamicSerializer<C: SerializationContext>: DynamicSerializerInner<C> {}
2541impl<C: SerializationContext, O: DynamicSerializerInner<C>> DynamicSerializer<C> for O {}
2542
2543#[derive(Copy, Clone)]
2544pub struct DynPartialSerializer<'a, C: SerializationContext>(
2545    &'a dyn DynamicPartialSerializerInner<C>,
2546);
2547
2548impl<'a, C: SerializationContext> DynPartialSerializer<'a, C> {
2549    pub fn new_dyn(s: &'a dyn DynamicPartialSerializerInner<C>) -> Self {
2550        Self(s)
2551    }
2552}
2553
2554impl<'a, C: SerializationContext> PartialSerializer<C> for DynPartialSerializer<'a, C> {
2555    fn partial_serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2556        &self,
2557        context: &mut C,
2558        constraints: PacketConstraints,
2559        alloc: A,
2560    ) -> Result<(B, usize), SerializeError<A::Error>> {
2561        let Self(inner) = self;
2562        let mut alloc = DynBufferAlloc::Alloc(alloc);
2563        let total_size = match inner.partial_serialize_dyn_alloc(context, constraints, &mut alloc) {
2564            Ok(result) => result,
2565            Err(SerializeError::SizeLimitExceeded) => {
2566                return Err(SerializeError::SizeLimitExceeded);
2567            }
2568            Err(SerializeError::Alloc(DynAllocError)) => {
2569                return Err(SerializeError::Alloc(alloc.take_error()));
2570            }
2571        };
2572
2573        let mut buffer = alloc.take_buffer();
2574        buffer.grow_front(
2575            buffer.prefix_len().checked_sub(constraints.header_len()).unwrap_or_else(|| {
2576                panic!(
2577                    "failed to grow buffer front; want: {} got: {}",
2578                    constraints.header_len(),
2579                    buffer.prefix_len()
2580                )
2581            }),
2582        );
2583        Ok((buffer, total_size))
2584    }
2585}
2586
2587impl<C: SerializationContext, O: PartialSerializer<C>> DynamicPartialSerializerInner<C> for O {
2588    fn partial_serialize_dyn_alloc(
2589        &self,
2590        context: &mut C,
2591        constraints: PacketConstraints,
2592        alloc: &mut dyn DynamicBufferAlloc,
2593    ) -> Result<usize, SerializeError<DynAllocError>> {
2594        self.partial_serialize_new_buf(context, constraints, DynamicBufferAllocAdapter(alloc))
2595            .map(|(_buf, total_size)| total_size)
2596    }
2597}
2598pub trait DynamicPartialSerializer<C: SerializationContext>:
2599    DynamicPartialSerializerInner<C>
2600{
2601}
2602
2603impl<C: SerializationContext, O: DynamicPartialSerializerInner<C>> DynamicPartialSerializer<C>
2604    for O
2605{
2606}
2607
2608#[cfg(test)]
2609mod tests {
2610    use super::*;
2611    use crate::BufferMut;
2612    use assert_matches::assert_matches;
2613    use core::fmt::Debug;
2614    use test_case::test_case;
2615    use test_util::{assert_geq, assert_leq};
2616
2617    fn dirty_buf_alloc(len: usize) -> Result<Buf<Vec<u8>>, !> {
2618        Ok(Buf::new(vec![0xAA; len], ..))
2619    }
2620
2621    // DummyPacketBuilder:
2622    // - Implements PacketBuilder with the stored constraints; it fills the
2623    //   header with header_byte and the footer with footer_byte
2624    // - Implements InnerPacketBuilder by consuming a `header_len`-bytes body,
2625    //   and filling it with header_byte
2626    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
2627    struct DummyPacketBuilder {
2628        header_len: usize,
2629        footer_len: usize,
2630        min_body_len: usize,
2631        max_body_len: usize,
2632        header_byte: u8,
2633        footer_byte: u8,
2634    }
2635
2636    impl DummyPacketBuilder {
2637        fn new(
2638            header_len: usize,
2639            footer_len: usize,
2640            min_body_len: usize,
2641            max_body_len: usize,
2642        ) -> DummyPacketBuilder {
2643            DummyPacketBuilder {
2644                header_len,
2645                footer_len,
2646                min_body_len,
2647                max_body_len,
2648                header_byte: 0xFF,
2649                footer_byte: 0xFE,
2650            }
2651        }
2652    }
2653
2654    impl NestablePacketBuilder for DummyPacketBuilder {
2655        fn constraints(&self) -> PacketConstraints {
2656            PacketConstraints::new(
2657                self.header_len,
2658                self.footer_len,
2659                self.min_body_len,
2660                self.max_body_len,
2661            )
2662        }
2663    }
2664
2665    impl<C: SerializationContext> PacketBuilder<C> for DummyPacketBuilder {
2666        fn serialize(
2667            &self,
2668            _context: &mut C,
2669            target: &mut SerializeTarget<'_>,
2670            body: FragmentedBytesMut<'_, '_>,
2671        ) {
2672            assert_eq!(target.header.len(), self.header_len);
2673            assert_eq!(target.footer.len(), self.footer_len);
2674            assert!(body.len() >= self.min_body_len);
2675            assert!(body.len() <= self.max_body_len);
2676            target.header.fill(self.header_byte);
2677            target.footer.fill(self.footer_byte);
2678        }
2679    }
2680
2681    impl<C: SerializationContext> PartialPacketBuilder<C> for DummyPacketBuilder {
2682        fn partial_serialize(&self, _context: &mut C, _body_len: usize, buffer: &mut [u8]) {
2683            buffer.fill(self.header_byte)
2684        }
2685    }
2686
2687    impl InnerPacketBuilder for DummyPacketBuilder {
2688        fn bytes_len(&self) -> usize {
2689            self.header_len
2690        }
2691
2692        fn serialize(&self, buffer: &mut [u8]) {
2693            assert_eq!(buffer.len(), self.header_len);
2694            buffer.fill(self.header_byte);
2695        }
2696    }
2697
2698    // Helper for `VerifyingSerializer` used to verify the serialization result.
2699    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
2700    struct SerializerVerifier {
2701        // Total size if the inner body if not truncated or `None` if
2702        // serialization is expected to fail due to size limit.
2703        inner_len: Option<usize>,
2704
2705        // Is the inner Serializer truncating (a TruncatingSerializer with
2706        // TruncateDirection::DiscardFront or DiscardBack)?
2707        truncating: bool,
2708    }
2709
2710    impl SerializerVerifier {
2711        fn new<S: Serializer<NoOpSerializationContext>>(serializer: &S, truncating: bool) -> Self {
2712            let inner_len = serializer
2713                .serialize_new_buf(
2714                    &mut NoOpSerializationContext,
2715                    PacketConstraints::UNCONSTRAINED,
2716                    new_buf_vec,
2717                )
2718                .map(|buf| buf.len())
2719                .inspect_err(|err| assert!(err.is_size_limit_exceeded()))
2720                .ok();
2721            Self { inner_len, truncating }
2722        }
2723
2724        fn verify_result<B: GrowBufferMut, A>(
2725            &self,
2726            result: Result<&B, &SerializeError<A>>,
2727            outer: PacketConstraints,
2728        ) {
2729            let should_exceed_size_limit = match self.inner_len {
2730                Some(inner_len) => outer.max_body_len() < inner_len && !self.truncating,
2731                None => true,
2732            };
2733
2734            match result {
2735                Ok(buf) => {
2736                    assert_geq!(buf.prefix_len(), outer.header_len());
2737                    assert_geq!(buf.suffix_len(), outer.footer_len());
2738                    assert_leq!(buf.len(), outer.max_body_len());
2739
2740                    // It is `Serialize::serialize()`'s responsibility to ensure that there
2741                    // is enough suffix room to fit any post-body padding and the footer,
2742                    // but it is the caller's responsibility to actually add that padding
2743                    // (ie, move it from the suffix to the body).
2744                    let padding = outer.min_body_len().saturating_sub(buf.len());
2745                    assert_leq!(padding + outer.footer_len(), buf.suffix_len());
2746
2747                    assert!(!should_exceed_size_limit);
2748                }
2749                Err(err) => {
2750                    // If we shouldn't fail as a result of a size limit exceeded
2751                    // error, we might still fail as a result of allocation.
2752                    if should_exceed_size_limit {
2753                        assert!(err.is_size_limit_exceeded());
2754                    } else {
2755                        assert!(err.is_alloc());
2756                    }
2757                }
2758            }
2759        }
2760    }
2761
2762    // A Serializer that verifies certain invariants while operating. In
2763    // particular:
2764    // - If serialization fails, the original Serializer is returned unmodified.
2765    // - If `outer.try_constraints()` returns `None`, serialization fails.
2766    // - If the size limit is exceeded and truncation is disabled, serialization
2767    //   fails.
2768    // - If serialization succeeds, the body has the correct length, including
2769    //   taking into account `outer`'s minimum body length requirement
2770    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
2771    struct VerifyingSerializer<S> {
2772        ser: S,
2773        verifier: SerializerVerifier,
2774    }
2775
2776    impl<S: Serializer<NoOpSerializationContext> + Debug + Clone + Eq>
2777        Serializer<NoOpSerializationContext> for VerifyingSerializer<S>
2778    where
2779        S::Buffer: ReusableBuffer,
2780    {
2781        type Buffer = S::Buffer;
2782
2783        fn serialize<B: GrowBufferMut, P: BufferProvider<Self::Buffer, B>>(
2784            self,
2785            context: &mut NoOpSerializationContext,
2786            constraints: PacketConstraints,
2787            provider: P,
2788        ) -> Result<B, (SerializeError<P::Error>, Self)> {
2789            let Self { ser, verifier } = self;
2790            let orig = ser.clone();
2791
2792            let result = ser.serialize(context, constraints, provider).map_err(|(err, ser)| {
2793                // If serialization fails, the original Serializer should be
2794                // unmodified.
2795                assert_eq!(ser, orig);
2796                (err, Self { ser, verifier })
2797            });
2798
2799            verifier.verify_result(result.as_ref().map_err(|(err, _ser)| err), constraints);
2800
2801            result
2802        }
2803
2804        fn serialize_new_buf<B: GrowBufferMut, A: LayoutBufferAlloc<B>>(
2805            &self,
2806            context: &mut NoOpSerializationContext,
2807            outer: PacketConstraints,
2808            alloc: A,
2809        ) -> Result<B, SerializeError<A::Error>> {
2810            let res = self.ser.serialize_new_buf(context, outer, alloc);
2811            self.verifier.verify_result(res.as_ref(), outer);
2812            res
2813        }
2814    }
2815
2816    impl<S> NestableSerializer for VerifyingSerializer<S> {}
2817
2818    trait SerializerExt: Serializer<NoOpSerializationContext> {
2819        fn into_verifying(self, truncating: bool) -> VerifyingSerializer<Self>
2820        where
2821            Self::Buffer: ReusableBuffer,
2822        {
2823            let verifier = SerializerVerifier::new(&self, truncating);
2824            VerifyingSerializer { ser: self, verifier }
2825        }
2826
2827        fn wrap_in_verifying<B: PacketBuilder<NoOpSerializationContext>>(
2828            self,
2829            outer: B,
2830            truncating: bool,
2831        ) -> VerifyingSerializer<Nested<Self, B>>
2832        where
2833            Self::Buffer: ReusableBuffer,
2834        {
2835            self.wrap_in(outer).into_verifying(truncating)
2836        }
2837
2838        fn with_size_limit_verifying(
2839            self,
2840            limit: usize,
2841            truncating: bool,
2842        ) -> VerifyingSerializer<Nested<Self, LimitedSizePacketBuilder>>
2843        where
2844            Self::Buffer: ReusableBuffer,
2845        {
2846            self.with_size_limit(limit).into_verifying(truncating)
2847        }
2848    }
2849
2850    impl<S: Serializer<NoOpSerializationContext>> SerializerExt for S {}
2851
2852    #[test]
2853    fn test_either_into_inner() {
2854        fn ret_either(a: u32, b: u32, c: bool) -> Either<u32, u32> {
2855            if c { Either::A(a) } else { Either::B(b) }
2856        }
2857
2858        assert_eq!(ret_either(1, 2, true).into_inner(), 1);
2859        assert_eq!(ret_either(1, 2, false).into_inner(), 2);
2860    }
2861
2862    #[test]
2863    fn test_either_unwrap_success() {
2864        assert_eq!(Either::<u16, u32>::A(5).unwrap_a(), 5);
2865        assert_eq!(Either::<u16, u32>::B(10).unwrap_b(), 10);
2866    }
2867
2868    #[test]
2869    #[should_panic]
2870    fn test_either_unwrap_a_panic() {
2871        let _: u16 = Either::<u16, u32>::B(10).unwrap_a();
2872    }
2873
2874    #[test]
2875    #[should_panic]
2876    fn test_either_unwrap_b_panic() {
2877        let _: u32 = Either::<u16, u32>::A(5).unwrap_b();
2878    }
2879
2880    #[test_case(Buf::new((0..100).collect(), ..); "entire buf")]
2881    #[test_case(Buf::new((0..100).collect(), 0..0); "empty range")]
2882    #[test_case(Buf::new((0..100).collect(), ..50); "prefix")]
2883    #[test_case(Buf::new((0..100).collect(), 50..); "suffix")]
2884    #[test_case(Buf::new((0..100).collect(), 25..75); "middle")]
2885    fn test_buf_into_inner(buf: Buf<Vec<u8>>) {
2886        assert_eq!(buf.clone().as_ref(), buf.into_inner());
2887    }
2888
2889    #[test]
2890    fn test_packet_constraints() {
2891        use PacketConstraints as PC;
2892
2893        // Test try_new
2894
2895        // Sanity check.
2896        assert!(PC::try_new(0, 0, 0, 0).is_some());
2897        // header_len + min_body_len + footer_len doesn't overflow usize
2898        assert!(PC::try_new(usize::MAX / 2, usize::MAX / 2, 0, 0).is_some());
2899        // header_len + min_body_len + footer_len overflows usize
2900        assert_eq!(PC::try_new(usize::MAX, 1, 0, 0), None);
2901        // min_body_len > max_body_len
2902        assert_eq!(PC::try_new(0, 0, 1, 0), None);
2903
2904        // Test PacketConstraints::try_encapsulate
2905
2906        // Sanity check.
2907        let pc = PC::new(10, 10, 0, usize::MAX);
2908        assert_eq!(pc.try_encapsulate(&pc).unwrap(), PC::new(20, 20, 0, usize::MAX - 20));
2909
2910        let pc = PC::new(10, 10, 0, usize::MAX);
2911        assert_eq!(pc.try_encapsulate(&pc).unwrap(), PC::new(20, 20, 0, usize::MAX - 20));
2912
2913        // Starting here, each failure test case corresponds to one check in
2914        // either PacketConstraints::try_encapsulate or PacketConstraints::new
2915        // (which is called from PacketConstraints::try_encapsulate). Each test
2916        // case is labeled "Test case N", and a corresponding comment in either
2917        // of those two functions identifies which line is being tested.
2918
2919        // The outer PC's minimum body length requirement of 10 is more than
2920        // satisfied by the inner PC's combined 20 bytes of header and footer.
2921        // The resulting PC has its minimum body length requirement saturated to
2922        // 0.
2923        let inner = PC::new(10, 10, 0, usize::MAX);
2924        let outer = PC::new(0, 0, 10, usize::MAX);
2925        assert_eq!(inner.try_encapsulate(&outer).unwrap(), PC::new(10, 10, 0, usize::MAX - 20));
2926
2927        // Test case 1
2928        //
2929        // The sum of the inner and outer header lengths overflows `usize`.
2930        let inner = PC::new(usize::MAX, 0, 0, usize::MAX);
2931        let outer = PC::new(1, 0, 0, usize::MAX);
2932        assert_eq!(inner.try_encapsulate(&outer), None);
2933
2934        // Test case 2
2935        //
2936        // The sum of the inner and outer footer lengths overflows `usize`.
2937        let inner = PC::new(0, usize::MAX, 0, usize::MAX);
2938        let outer = PC::new(0, 1, 0, usize::MAX);
2939        assert_eq!(inner.try_encapsulate(&outer), None);
2940
2941        // Test case 3
2942        //
2943        // The sum of the resulting header, footer, and minimum body lengths
2944        // overflows `usize`. We use usize::MAX / 5 + 1 as the constant so that
2945        // none of the intermediate additions overflow, so we make sure to test
2946        // that an overflow in the final addition will be caught.
2947        let one_fifth_max = (usize::MAX / 5) + 1;
2948        let inner = PC::new(one_fifth_max, one_fifth_max, one_fifth_max, usize::MAX);
2949        let outer = PC::new(one_fifth_max, one_fifth_max, 0, usize::MAX);
2950        assert_eq!(inner.try_encapsulate(&outer), None);
2951
2952        // Test case 4
2953        //
2954        // The header and footer of the inner PC exceed the maximum body length
2955        // requirement of the outer PC.
2956        let inner = PC::new(10, 10, 0, usize::MAX);
2957        let outer = PC::new(0, 0, 0, 10);
2958        assert_eq!(inner.try_encapsulate(&outer), None);
2959
2960        // Test case 5
2961        //
2962        // The resulting minimum body length (thanks to the inner
2963        // PacketBuilder's minimum body length) is larger than the resulting
2964        // maximum body length.
2965        let inner = PC::new(0, 0, 10, usize::MAX);
2966        let outer = PC::new(0, 0, 0, 5);
2967        assert_eq!(inner.try_encapsulate(&outer), None);
2968    }
2969
2970    #[test]
2971    fn test_inner_serializer() {
2972        const INNER: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2973
2974        fn concat<'a, I: IntoIterator<Item = &'a &'a [u8]>>(slices: I) -> Vec<u8> {
2975            let mut v = Vec::new();
2976            for slc in slices.into_iter() {
2977                v.extend_from_slice(slc);
2978            }
2979            v
2980        }
2981
2982        // Sanity check.
2983        let buf =
2984            INNER.into_serializer().serialize_vec_outer(&mut NoOpSerializationContext).unwrap();
2985        assert_eq!(buf.as_ref(), INNER);
2986
2987        // A larger minimum body length requirement will cause padding to be
2988        // added.
2989        let buf = INNER
2990            .into_serializer()
2991            .into_verifying(false)
2992            .wrap_in(DummyPacketBuilder::new(0, 0, 20, usize::MAX))
2993            .serialize_vec_outer(&mut NoOpSerializationContext)
2994            .unwrap();
2995        assert_eq!(buf.as_ref(), concat(&[INNER, vec![0; 10].as_ref()]).as_slice());
2996
2997        // Headers and footers are added as appropriate (note that
2998        // DummyPacketBuilder fills its header with 0xFF and its footer with
2999        // 0xFE).
3000        let buf = INNER
3001            .into_serializer()
3002            .into_verifying(false)
3003            .wrap_in(DummyPacketBuilder::new(10, 10, 0, usize::MAX))
3004            .serialize_vec_outer(&mut NoOpSerializationContext)
3005            .unwrap();
3006        assert_eq!(
3007            buf.as_ref(),
3008            concat(&[vec![0xFF; 10].as_ref(), INNER, vec![0xFE; 10].as_ref()]).as_slice()
3009        );
3010
3011        // An exceeded maximum body size is rejected.
3012        assert_eq!(
3013            INNER
3014                .into_serializer()
3015                .into_verifying(false)
3016                .wrap_in(DummyPacketBuilder::new(0, 0, 0, 9))
3017                .serialize_vec_outer(&mut NoOpSerializationContext)
3018                .unwrap_err()
3019                .0,
3020            SerializeError::SizeLimitExceeded
3021        );
3022
3023        // `into_serializer_with` truncates the buffer's body to zero before
3024        // returning, so those body bytes are not included in the serialized
3025        // output.
3026        assert_eq!(
3027            INNER
3028                .into_serializer_with(Buf::new(vec![0xFF], ..))
3029                .into_verifying(false)
3030                .serialize_vec_outer(&mut NoOpSerializationContext)
3031                .unwrap()
3032                .as_ref(),
3033            INNER
3034        );
3035    }
3036
3037    #[test]
3038    fn test_buffer_serializer_and_inner_serializer() {
3039        fn verify_buffer_serializer<B: BufferMut + Debug>(
3040            buffer: B,
3041            header_len: usize,
3042            footer_len: usize,
3043            min_body_len: usize,
3044        ) {
3045            let old_body = buffer.to_flattened_vec();
3046            let serializer =
3047                DummyPacketBuilder::new(header_len, footer_len, min_body_len, usize::MAX)
3048                    .wrap_body(buffer);
3049
3050            let buffer0 = serializer
3051                .serialize_new_buf(
3052                    &mut NoOpSerializationContext,
3053                    PacketConstraints::UNCONSTRAINED,
3054                    dirty_buf_alloc,
3055                )
3056                .unwrap();
3057            verify(buffer0, &old_body, header_len, footer_len, min_body_len);
3058
3059            let buffer = serializer.serialize_vec_outer(&mut NoOpSerializationContext).unwrap();
3060            verify(buffer, &old_body, header_len, footer_len, min_body_len);
3061        }
3062
3063        fn verify_inner_packet_builder_serializer(
3064            body: &[u8],
3065            header_len: usize,
3066            footer_len: usize,
3067            min_body_len: usize,
3068        ) {
3069            let buffer = DummyPacketBuilder::new(header_len, footer_len, min_body_len, usize::MAX)
3070                .wrap_body(body.into_serializer())
3071                .serialize_vec_outer(&mut NoOpSerializationContext)
3072                .unwrap();
3073            verify(buffer, body, header_len, footer_len, min_body_len);
3074        }
3075
3076        fn verify<B: Buffer>(
3077            buffer: B,
3078            body: &[u8],
3079            header_len: usize,
3080            footer_len: usize,
3081            min_body_len: usize,
3082        ) {
3083            let flat = buffer.to_flattened_vec();
3084            let header_bytes = &flat[..header_len];
3085            let body_bytes = &flat[header_len..header_len + body.len()];
3086            let padding_len = min_body_len.saturating_sub(body.len());
3087            let padding_bytes =
3088                &flat[header_len + body.len()..header_len + body.len() + padding_len];
3089            let total_body_len = body.len() + padding_len;
3090            let footer_bytes = &flat[header_len + total_body_len..];
3091            assert_eq!(
3092                buffer.len() - total_body_len,
3093                header_len + footer_len,
3094                "buffer.len()({}) - total_body_len({}) != header_len({}) + footer_len({})",
3095                buffer.len(),
3096                header_len,
3097                footer_len,
3098                min_body_len,
3099            );
3100
3101            // DummyPacketBuilder fills its header with 0xFF
3102            assert!(
3103                header_bytes.iter().all(|b| *b == 0xFF),
3104                "header_bytes {:?} are not filled with 0xFF's",
3105                header_bytes,
3106            );
3107            assert_eq!(body_bytes, body);
3108            // Padding bytes must be initialized to zero
3109            assert!(
3110                padding_bytes.iter().all(|b| *b == 0),
3111                "padding_bytes {:?} are not filled with 0s",
3112                padding_bytes,
3113            );
3114            // DummyPacketBuilder fills its footer with 0xFE
3115            assert!(
3116                footer_bytes.iter().all(|b| *b == 0xFE),
3117                "footer_bytes {:?} are not filled with 0xFE's",
3118                footer_bytes,
3119            );
3120        }
3121
3122        // Test for every valid combination of buf_len, range_start, range_end,
3123        // prefix, suffix, and min_body within [0, 8).
3124        for buf_len in 0..8 {
3125            for range_start in 0..buf_len {
3126                for range_end in range_start..buf_len {
3127                    for prefix in 0..8 {
3128                        for suffix in 0..8 {
3129                            for min_body in 0..8 {
3130                                let mut vec = vec![0; buf_len];
3131                                // Initialize the vector with values 0, 1, 2,
3132                                // ... so that we can check to make sure that
3133                                // the range bytes have been properly copied if
3134                                // the buffer is reallocated.
3135                                #[allow(clippy::needless_range_loop)]
3136                                for i in 0..vec.len() {
3137                                    vec[i] = i as u8;
3138                                }
3139                                verify_buffer_serializer(
3140                                    Buf::new(vec.as_mut_slice(), range_start..range_end),
3141                                    prefix,
3142                                    suffix,
3143                                    min_body,
3144                                );
3145                                if range_start == 0 {
3146                                    // Unlike verify_buffer_serializer, this
3147                                    // test doesn't make use of the prefix or
3148                                    // suffix. In order to avoid running the
3149                                    // exact same test multiple times, we only
3150                                    // run this when `range_start == 0`, which
3151                                    // has the effect of reducing the number of
3152                                    // times that this test is run by roughly a
3153                                    // factor of 8.
3154                                    verify_inner_packet_builder_serializer(
3155                                        &vec.as_slice()[range_start..range_end],
3156                                        prefix,
3157                                        suffix,
3158                                        min_body,
3159                                    );
3160                                }
3161                            }
3162                        }
3163                    }
3164                }
3165            }
3166        }
3167    }
3168
3169    #[test]
3170    fn test_min_body_len() {
3171        // Test that padding is added after the body of the packet whose minimum
3172        // body length constraint requires it. A previous version of this code
3173        // had a bug where padding was always added after the innermost body.
3174
3175        let body = &[1, 2];
3176
3177        // 4 bytes of header and footer for a total of 6 bytes (including the
3178        // body).
3179        let inner = DummyPacketBuilder::new(2, 2, 0, usize::MAX);
3180        // Minimum body length of 8 will require 2 bytes of padding.
3181        let outer = DummyPacketBuilder::new(2, 2, 8, usize::MAX);
3182        let buf = body
3183            .into_serializer()
3184            .into_verifying(false)
3185            .wrap_in_verifying(inner, false)
3186            .wrap_in_verifying(outer, false)
3187            .serialize_vec_outer(&mut NoOpSerializationContext)
3188            .unwrap();
3189        assert_eq!(buf.prefix_len(), 0);
3190        assert_eq!(buf.suffix_len(), 0);
3191        assert_eq!(
3192            buf.as_ref(),
3193            &[
3194                0xFF, 0xFF, // Outer header
3195                0xFF, 0xFF, // Inner header
3196                1, 2, // Inner body
3197                0xFE, 0xFE, // Inner footer
3198                0, 0, // Padding to satisfy outer minimum body length requirement
3199                0xFE, 0xFE // Outer footer
3200            ]
3201        );
3202    }
3203
3204    #[test]
3205    fn test_size_limit() {
3206        // ser is a Serializer that will consume 1 byte of buffer space
3207        fn test<S: Serializer<NoOpSerializationContext> + Clone + Debug + Eq>(ser: S)
3208        where
3209            S::Buffer: ReusableBuffer,
3210        {
3211            // Each of these tests encapsulates ser in a DummyPacketBuilder
3212            // which consumes 1 byte for the header and one byte for the footer.
3213            // Thus, the inner serializer will consume 1 byte, while the
3214            // DummyPacketBuilder will consume 2 bytes, for a total of 3 bytes.
3215
3216            let pb = DummyPacketBuilder::new(1, 1, 0, usize::MAX);
3217
3218            // Test that a size limit of 3 is OK. Note that this is an important
3219            // test since it tests the case when the size limit is exactly
3220            // sufficient. A previous version of this code had a bug where a
3221            // packet which fit the size limit exactly would be rejected.
3222            assert!(
3223                ser.clone()
3224                    .wrap_in_verifying(pb, false)
3225                    .with_size_limit_verifying(3, false)
3226                    .serialize_vec_outer(&mut NoOpSerializationContext)
3227                    .is_ok()
3228            );
3229            // Test that a more-than-large-enough size limit of 4 is OK.
3230            assert!(
3231                ser.clone()
3232                    .wrap_in_verifying(pb, false)
3233                    .with_size_limit_verifying(4, false)
3234                    .serialize_vec_outer(&mut NoOpSerializationContext)
3235                    .is_ok()
3236            );
3237            // Test that the inner size limit of 1 only applies to the inner
3238            // serializer, and so is still OK even though the outer serializer
3239            // consumes 3 bytes total.
3240            assert!(
3241                ser.clone()
3242                    .with_size_limit_verifying(1, false)
3243                    .wrap_in_verifying(pb, false)
3244                    .with_size_limit_verifying(3, false)
3245                    .serialize_vec_outer(&mut NoOpSerializationContext)
3246                    .is_ok()
3247            );
3248            // Test that the inner size limit of 0 is exceeded by the inner
3249            // serializer's 1 byte length.
3250            assert!(
3251                ser.clone()
3252                    .with_size_limit_verifying(0, false)
3253                    .wrap_in_verifying(pb, false)
3254                    .serialize_vec_outer(&mut NoOpSerializationContext)
3255                    .is_err()
3256            );
3257            // Test that a size limit which would be exceeded by the
3258            // encapsulating layer is rejected by Nested's implementation. If
3259            // this doesn't work properly, then the size limit should underflow,
3260            // resulting in a panic (see the Nested implementation of
3261            // Serialize).
3262            assert!(
3263                ser.clone()
3264                    .wrap_in_verifying(pb, false)
3265                    .with_size_limit_verifying(1, false)
3266                    .serialize_vec_outer(&mut NoOpSerializationContext)
3267                    .is_err()
3268            );
3269        }
3270
3271        // We use this as an InnerPacketBuilder which consumes 1 byte of body.
3272        test(DummyPacketBuilder::new(1, 0, 0, usize::MAX).into_serializer().into_verifying(false));
3273        test(Buf::new(vec![0], ..).into_verifying(false));
3274    }
3275
3276    #[test]
3277    fn test_truncating_serializer() {
3278        fn verify_result<S: Serializer<NoOpSerializationContext> + Debug>(ser: S, expected: &[u8])
3279        where
3280            S::Buffer: ReusableBuffer + AsRef<[u8]>,
3281        {
3282            let buf = ser
3283                .serialize_new_buf(
3284                    &mut NoOpSerializationContext,
3285                    PacketConstraints::UNCONSTRAINED,
3286                    new_buf_vec,
3287                )
3288                .unwrap();
3289            assert_eq!(buf.as_ref(), &expected[..]);
3290            let buf = ser.serialize_vec_outer(&mut NoOpSerializationContext).unwrap();
3291            assert_eq!(buf.as_ref(), &expected[..]);
3292        }
3293
3294        // Test truncate front.
3295        let body = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3296        let ser =
3297            TruncatingSerializer::new(Buf::new(body.clone(), ..), TruncateDirection::DiscardFront)
3298                .into_verifying(true)
3299                .with_size_limit_verifying(4, true);
3300        verify_result(ser, &[6, 7, 8, 9]);
3301
3302        // Test truncate back.
3303        let ser =
3304            TruncatingSerializer::new(Buf::new(body.clone(), ..), TruncateDirection::DiscardBack)
3305                .into_verifying(true)
3306                .with_size_limit_verifying(7, true);
3307        verify_result(ser, &[0, 1, 2, 3, 4, 5, 6]);
3308
3309        // Test no truncating (default/original case).
3310        let ser =
3311            TruncatingSerializer::new(Buf::new(body.clone(), ..), TruncateDirection::NoTruncating)
3312                .into_verifying(false)
3313                .with_size_limit_verifying(5, true);
3314        assert!(ser.clone().serialize_vec_outer(&mut NoOpSerializationContext).is_err());
3315        assert!(
3316            ser.serialize_new_buf(
3317                &mut NoOpSerializationContext,
3318                PacketConstraints::UNCONSTRAINED,
3319                new_buf_vec
3320            )
3321            .is_err()
3322        );
3323        assert!(ser.serialize_vec_outer(&mut NoOpSerializationContext).is_err());
3324
3325        // Test that, when serialization fails, any truncation is undone.
3326
3327        // `ser` has a body of `[1, 2]` and no prefix or suffix
3328        fn test_serialization_failure<
3329            S: Serializer<NoOpSerializationContext> + Clone + Eq + Debug,
3330        >(
3331            ser: S,
3332            err: SerializeError<BufferTooShortError>,
3333        ) where
3334            S::Buffer: ReusableBuffer + Debug,
3335        {
3336            // Serialize with a PacketBuilder with a size limit of 1 so that the
3337            // body (of length 2) is too large. If `ser` is configured not to
3338            // truncate, it should result in a size limit error. If it is
3339            // configured to truncate, the 2 + 2 = 4 combined bytes of header
3340            // and footer will cause allocating a new buffer to fail, and it
3341            // should result in an allocation failure. Even if the body was
3342            // truncated, it should be returned to its original un-truncated
3343            // state before being returned from `serialize`.
3344            let (e, new_ser) = DummyPacketBuilder::new(2, 2, 0, 1)
3345                .wrap_body(ser.clone())
3346                .serialize_no_alloc_outer(&mut NoOpSerializationContext)
3347                .unwrap_err();
3348            assert_eq!(err, e);
3349            assert_eq!(new_ser.into_inner(), ser);
3350        }
3351
3352        let body = Buf::new(vec![1, 2], ..);
3353        test_serialization_failure(
3354            TruncatingSerializer::new(body.clone(), TruncateDirection::DiscardFront)
3355                .into_verifying(true),
3356            SerializeError::Alloc(BufferTooShortError),
3357        );
3358        test_serialization_failure(
3359            TruncatingSerializer::new(body.clone(), TruncateDirection::DiscardFront)
3360                .into_verifying(true),
3361            SerializeError::Alloc(BufferTooShortError),
3362        );
3363        test_serialization_failure(
3364            TruncatingSerializer::new(body.clone(), TruncateDirection::NoTruncating)
3365                .into_verifying(false),
3366            SerializeError::SizeLimitExceeded,
3367        );
3368    }
3369
3370    // Regression test for a bug in the directionality of constraints
3371    // encapsulation in nested partial serialization: an outer packet should be
3372    // able to encapsulate an inner packet whose constraints it would violate if
3373    // the encapsulation were reversed.
3374    #[test]
3375    fn nested_partial_serialize_constraints() {
3376        const BODY: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3377        const INNER_PACKET_MAX_BODY: usize = 10;
3378        const EXPECTED_HEADER: &[u8] = &[0xFF; 20];
3379
3380        let packet = BODY
3381            .into_serializer()
3382            .wrap_in(DummyPacketBuilder::new(0, 0, 0, INNER_PACKET_MAX_BODY))
3383            .wrap_in(DummyPacketBuilder::new(2 * INNER_PACKET_MAX_BODY, 0, 0, usize::MAX));
3384        let result = packet.partial_serialize(&mut NoOpSerializationContext, new_buf_vec);
3385        let buffer = assert_matches!(
3386            result,
3387            Ok(PartialSerializeResult::NewBuffer { buffer, total_size: 30 }) => buffer);
3388        assert_eq!(buffer.as_ref(), EXPECTED_HEADER);
3389    }
3390
3391    #[test]
3392    fn test_try_reuse_buffer() {
3393        fn test_expect_success(
3394            body_range: Range<usize>,
3395            prefix: usize,
3396            suffix: usize,
3397            max_copy_bytes: usize,
3398        ) {
3399            let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3400            let buffer = Buf::new(&mut bytes[..], body_range);
3401            let body = buffer.as_ref().to_vec();
3402            let buffer = try_reuse_buffer(buffer, prefix, suffix, max_copy_bytes).unwrap();
3403            assert_eq!(buffer.as_ref(), body.as_slice());
3404            assert!(buffer.prefix_len() >= prefix);
3405            assert!(buffer.suffix_len() >= suffix);
3406        }
3407
3408        fn test_expect_failure(
3409            body_range: Range<usize>,
3410            prefix: usize,
3411            suffix: usize,
3412            max_copy_bytes: usize,
3413        ) {
3414            let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3415            let buffer = Buf::new(&mut bytes[..], body_range.clone());
3416            let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3417            let orig = Buf::new(&mut bytes[..], body_range.clone());
3418            let buffer = try_reuse_buffer(buffer, prefix, suffix, max_copy_bytes).unwrap_err();
3419            assert_eq!(buffer, orig);
3420        }
3421
3422        // No prefix or suffix trivially succeeds.
3423        test_expect_success(0..10, 0, 0, 0);
3424        // If we have enough prefix/suffix, it succeeds.
3425        test_expect_success(1..9, 1, 1, 0);
3426        // If we don't have enough prefix/suffix, but we have enough capacity to
3427        // move the buffer within the body, it succeeds...
3428        test_expect_success(0..9, 1, 0, 9);
3429        test_expect_success(1..10, 0, 1, 9);
3430        // ...but if we don't provide a large enough max_copy_bytes, it will fail.
3431        test_expect_failure(0..9, 1, 0, 8);
3432        test_expect_failure(1..10, 0, 1, 8);
3433    }
3434
3435    #[test]
3436    fn test_maybe_reuse_buffer_provider() {
3437        fn test_expect(body_range: Range<usize>, prefix: usize, suffix: usize, expect_a: bool) {
3438            let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3439            let buffer = Buf::new(&mut bytes[..], body_range);
3440            let body = buffer.as_ref().to_vec();
3441            let buffer = BufferProvider::reuse_or_realloc(
3442                MaybeReuseBufferProvider(new_buf_vec),
3443                buffer,
3444                prefix,
3445                suffix,
3446            )
3447            .unwrap();
3448            match &buffer {
3449                Either::A(_) if expect_a => {}
3450                Either::B(_) if !expect_a => {}
3451                Either::A(_) => panic!("expected Eitehr::B variant"),
3452                Either::B(_) => panic!("expected Eitehr::A variant"),
3453            }
3454            let bytes: &[u8] = buffer.as_ref();
3455            assert_eq!(bytes, body.as_slice());
3456            assert!(buffer.prefix_len() >= prefix);
3457            assert!(buffer.suffix_len() >= suffix);
3458        }
3459
3460        // Expect that we'll be able to reuse the existing buffer.
3461        fn test_expect_reuse(body_range: Range<usize>, prefix: usize, suffix: usize) {
3462            test_expect(body_range, prefix, suffix, true);
3463        }
3464
3465        // Expect that we'll need to allocate a new buffer.
3466        fn test_expect_realloc(body_range: Range<usize>, prefix: usize, suffix: usize) {
3467            test_expect(body_range, prefix, suffix, false);
3468        }
3469
3470        // No prefix or suffix trivially succeeds.
3471        test_expect_reuse(0..10, 0, 0);
3472        // If we have enough prefix/suffix, it succeeds.
3473        test_expect_reuse(1..9, 1, 1);
3474        // If we don't have enough prefix/suffix, but we have enough capacity to
3475        // move the buffer within the body, it succeeds.
3476        test_expect_reuse(0..9, 1, 0);
3477        test_expect_reuse(1..10, 0, 1);
3478        // If we don't have enough capacity, it fails and must realloc.
3479        test_expect_realloc(0..9, 1, 1);
3480        test_expect_realloc(1..10, 1, 1);
3481    }
3482
3483    #[test]
3484    fn test_no_reuse_buffer_provider() {
3485        #[track_caller]
3486        fn test_expect(body_range: Range<usize>, prefix: usize, suffix: usize) {
3487            let mut bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
3488            // The buffer that will not be reused.
3489            let internal_buffer: Buf<&mut [u8]> = Buf::new(&mut bytes[..], body_range);
3490            let body = internal_buffer.as_ref().to_vec();
3491            // The newly allocated buffer, note the type is different from
3492            // internal_buffer.
3493            let buffer: Buf<Vec<u8>> = BufferProvider::reuse_or_realloc(
3494                NoReuseBufferProvider(new_buf_vec),
3495                internal_buffer,
3496                prefix,
3497                suffix,
3498            )
3499            .unwrap();
3500            let bytes: &[u8] = buffer.as_ref();
3501            assert_eq!(bytes, body.as_slice());
3502            assert_eq!(buffer.prefix_len(), prefix);
3503            assert_eq!(buffer.suffix_len(), suffix);
3504        }
3505        // No prefix or suffix trivially succeeds, reuse opportunity is ignored.
3506        test_expect(0..10, 0, 0);
3507        // If we have enough prefix/suffix, reuse opportunity is ignored.
3508        test_expect(1..9, 1, 1);
3509        // Prefix and suffix and properly allocated and the body is copied.
3510        test_expect(0..9, 10, 10);
3511        test_expect(1..10, 15, 15);
3512    }
3513
3514    /// Simple Vec-backed buffer to test fragmented buffers implementation.
3515    ///
3516    /// `ScatterGatherBuf` keeps:
3517    /// - an inner buffer `inner`, which is always part of its body.
3518    /// - extra backing memory in `data`.
3519    ///
3520    /// `data` has two "root" regions, marked by the midpoint `mid`. Everything
3521    /// left of `mid` is this buffer's prefix, and after `mid` is this buffer's
3522    /// suffix.
3523    ///
3524    /// The `range` field keeps the range in `data` that contains *filled*
3525    /// prefix and suffix information. `range.start` is always less than or
3526    /// equal to `mid` and `range.end` is always greater than or equal to `mid`,
3527    /// such that growing the front of the buffer means decrementing
3528    /// `range.start` and growing the back of the buffer means incrementing
3529    /// `range.end`.
3530    ///
3531    ///  At any time this buffer's parts are:
3532    /// - Free prefix data in range `0..range.start`.
3533    /// - Used prefix data (now part of body) in range `range.start..mid`.
3534    /// - Inner buffer body in `inner`.
3535    /// - Used suffix data (now part of body) in range `mid..range.end`.
3536    /// - Free suffix data in range `range.end..`
3537    struct ScatterGatherBuf<B> {
3538        data: Vec<u8>,
3539        mid: usize,
3540        range: Range<usize>,
3541        inner: B,
3542    }
3543
3544    impl<B: BufferMut> FragmentedBuffer for ScatterGatherBuf<B> {
3545        fn len(&self) -> usize {
3546            self.inner.len() + (self.range.end - self.range.start)
3547        }
3548
3549        fn with_bytes<'a, R, F>(&'a self, f: F) -> R
3550        where
3551            F: for<'b> FnOnce(FragmentedBytes<'b, 'a>) -> R,
3552        {
3553            let (_, rest) = self.data.split_at(self.range.start);
3554            let (prefix_b, rest) = rest.split_at(self.mid - self.range.start);
3555            let (suffix_b, _) = rest.split_at(self.range.end - self.mid);
3556            let mut bytes = [prefix_b, self.inner.as_ref(), suffix_b];
3557            f(FragmentedBytes::new(&mut bytes[..]))
3558        }
3559    }
3560
3561    impl<B: BufferMut> FragmentedBufferMut for ScatterGatherBuf<B> {
3562        fn with_bytes_mut<'a, R, F>(&'a mut self, f: F) -> R
3563        where
3564            F: for<'b> FnOnce(FragmentedBytesMut<'b, 'a>) -> R,
3565        {
3566            let (_, rest) = self.data.split_at_mut(self.range.start);
3567            let (prefix_b, rest) = rest.split_at_mut(self.mid - self.range.start);
3568            let (suffix_b, _) = rest.split_at_mut(self.range.end - self.mid);
3569            let mut bytes = [prefix_b, self.inner.as_mut(), suffix_b];
3570            f(FragmentedBytesMut::new(&mut bytes[..]))
3571        }
3572    }
3573
3574    impl<B: BufferMut> GrowBuffer for ScatterGatherBuf<B> {
3575        fn with_parts<'a, O, F>(&'a self, f: F) -> O
3576        where
3577            F: for<'b> FnOnce(&'a [u8], FragmentedBytes<'b, 'a>, &'a [u8]) -> O,
3578        {
3579            let (prefix, rest) = self.data.split_at(self.range.start);
3580            let (prefix_b, rest) = rest.split_at(self.mid - self.range.start);
3581            let (suffix_b, suffix) = rest.split_at(self.range.end - self.mid);
3582            let mut bytes = [prefix_b, self.inner.as_ref(), suffix_b];
3583            f(prefix, bytes.as_fragmented_byte_slice(), suffix)
3584        }
3585        fn prefix_len(&self) -> usize {
3586            self.range.start
3587        }
3588
3589        fn suffix_len(&self) -> usize {
3590            self.data.len() - self.range.end
3591        }
3592
3593        fn grow_front(&mut self, n: usize) {
3594            self.range.start -= n;
3595        }
3596
3597        fn grow_back(&mut self, n: usize) {
3598            self.range.end += n;
3599            assert!(self.range.end <= self.data.len());
3600        }
3601    }
3602
3603    impl<B: BufferMut> GrowBufferMut for ScatterGatherBuf<B> {
3604        fn with_parts_mut<'a, O, F>(&'a mut self, f: F) -> O
3605        where
3606            F: for<'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'b, 'a>, &'a mut [u8]) -> O,
3607        {
3608            let (prefix, rest) = self.data.split_at_mut(self.range.start);
3609            let (prefix_b, rest) = rest.split_at_mut(self.mid - self.range.start);
3610            let (suffix_b, suffix) = rest.split_at_mut(self.range.end - self.mid);
3611            let mut bytes = [prefix_b, self.inner.as_mut(), suffix_b];
3612            f(prefix, bytes.as_fragmented_byte_slice(), suffix)
3613        }
3614
3615        fn with_all_contents_mut<'a, O, F>(&'a mut self, _f: F) -> O
3616        where
3617            F: for<'b> FnOnce(FragmentedBytesMut<'b, 'a>) -> O,
3618        {
3619            unimplemented!()
3620        }
3621    }
3622
3623    struct ScatterGatherProvider;
3624
3625    impl<B: BufferMut> BufferProvider<B, ScatterGatherBuf<B>> for ScatterGatherProvider {
3626        type Error = !;
3627
3628        fn alloc_no_reuse(
3629            self,
3630            _prefix: usize,
3631            _body: usize,
3632            _suffix: usize,
3633        ) -> Result<ScatterGatherBuf<B>, Self::Error> {
3634            unimplemented!("not used in tests")
3635        }
3636
3637        fn reuse_or_realloc(
3638            self,
3639            buffer: B,
3640            prefix: usize,
3641            suffix: usize,
3642        ) -> Result<ScatterGatherBuf<B>, (Self::Error, B)> {
3643            let inner = buffer;
3644            let data = vec![0; prefix + suffix];
3645            let range = Range { start: prefix, end: prefix };
3646            let mid = prefix;
3647            Ok(ScatterGatherBuf { inner, data, range, mid })
3648        }
3649    }
3650
3651    #[test]
3652    fn test_scatter_gather_serialize() {
3653        // Assert that a buffer composed of different allocations can be used as
3654        // a serialization target, while reusing an internal body buffer.
3655        let buf = Buf::new(vec![10, 20, 30, 40, 50], ..);
3656        let pb = DummyPacketBuilder::new(3, 2, 0, usize::MAX);
3657        let ser = pb.wrap_body(buf);
3658        let result =
3659            ser.serialize_outer(&mut NoOpSerializationContext, ScatterGatherProvider {}).unwrap();
3660        let flattened = result.to_flattened_vec();
3661        assert_eq!(&flattened[..], &[0xFF, 0xFF, 0xFF, 10, 20, 30, 40, 50, 0xFE, 0xFE]);
3662    }
3663
3664    #[test]
3665    fn dyn_serialize() {
3666        let body = Buf::new(vec![10, 20, 30, 40, 50], ..);
3667        let header1 = DummyPacketBuilder {
3668            header_len: 5,
3669            footer_len: 0,
3670            min_body_len: 0,
3671            max_body_len: usize::MAX,
3672            header_byte: 0xAA,
3673            footer_byte: 0xBB,
3674        };
3675        let header2 = DummyPacketBuilder {
3676            header_len: 3,
3677            footer_len: 2,
3678            min_body_len: 0,
3679            max_body_len: usize::MAX,
3680            header_byte: 0xCC,
3681            footer_byte: 0xDD,
3682        };
3683        // A reference serializer.
3684        let ser1 = body.clone().wrap_in(header1).wrap_in(header2);
3685        // A nested dynamic serializer.
3686        let ser2 = body.wrap_in(header1);
3687        let ser2 = DynSerializer::new(&ser2).wrap_in(header2);
3688        // An outer dynamic serializer.
3689        let ser3 = ser1.clone();
3690        let ser3 = DynSerializer::new(&ser3);
3691        // Two levels of dynamic serializer.
3692        let ser4 = DynSerializer::new(&ser2);
3693
3694        fn serialize(
3695            s: impl Serializer<NoOpSerializationContext, Buffer: ReusableBuffer>,
3696        ) -> Vec<u8> {
3697            s.serialize_vec(&mut NoOpSerializationContext, PacketConstraints::UNCONSTRAINED)
3698                .map_err(|(e, _)| e)
3699                .unwrap()
3700                .unwrap_b()
3701                .into_inner()
3702        }
3703
3704        fn serialize_new(s: impl Serializer<NoOpSerializationContext>) -> Vec<u8> {
3705            s.serialize_new_buf(
3706                &mut NoOpSerializationContext,
3707                PacketConstraints::UNCONSTRAINED,
3708                new_buf_vec,
3709            )
3710            .unwrap()
3711            .into_inner()
3712        }
3713
3714        let expect = serialize(ser1.clone());
3715        assert_eq!(serialize(ser2), expect);
3716        assert_eq!(serialize(ser3), expect);
3717        assert_eq!(serialize(ser4), expect);
3718        assert_eq!(serialize_new(ser1), expect);
3719        assert_eq!(serialize_new(ser2), expect);
3720        assert_eq!(serialize_new(ser3), expect);
3721        assert_eq!(serialize_new(ser4), expect);
3722    }
3723
3724    /// SerializationContext that tracks the `header_len()` of the outer
3725    /// `PacketBuilder`s it sees.
3726    struct TrackingSerializationContext {
3727        history: Vec<usize>,
3728    }
3729
3730    impl SerializationContext for TrackingSerializationContext {
3731        type ContextState = ();
3732
3733        fn serialize_nested<O: PacketBuilder<Self>, R>(
3734            &mut self,
3735            outer: &O,
3736            constraints: PacketConstraints,
3737            serialize_fn: impl FnOnce(&mut Self, PacketConstraints) -> R,
3738        ) -> R {
3739            self.history.push(outer.constraints().header_len());
3740            serialize_fn(self, constraints)
3741        }
3742    }
3743
3744    #[test]
3745    fn nested_serializer_context_aware() {
3746        let body = Buf::new(vec![0; 10], ..);
3747
3748        let outer = DummyPacketBuilder::new(3, 0, 0, usize::MAX);
3749        let middle = DummyPacketBuilder::new(2, 0, 0, usize::MAX);
3750        let inner = DummyPacketBuilder::new(1, 0, 0, usize::MAX);
3751
3752        let serializer = body.wrap_in(inner).wrap_in(middle).wrap_in(outer);
3753
3754        let mut context = TrackingSerializationContext { history: Vec::new() };
3755        let _buf = serializer.clone().serialize_vec_outer(&mut context).unwrap();
3756        assert_eq!(context.history, vec![3, 2, 1]);
3757
3758        let mut context = TrackingSerializationContext { history: Vec::new() };
3759        let _buf = serializer
3760            .serialize_new_buf(&mut context, PacketConstraints::UNCONSTRAINED, new_buf_vec)
3761            .unwrap();
3762        assert_eq!(context.history, vec![3, 2, 1]);
3763    }
3764
3765    #[test]
3766    fn nested_partial_serializer_context_aware() {
3767        let body = Buf::new(vec![0; 10], ..);
3768
3769        let outer = DummyPacketBuilder::new(3, 0, 0, usize::MAX);
3770        let middle = DummyPacketBuilder::new(2, 0, 0, usize::MAX);
3771        let inner = DummyPacketBuilder::new(1, 0, 0, usize::MAX);
3772
3773        let serializer = body.wrap_in(inner).wrap_in(middle).wrap_in(outer);
3774
3775        let mut context = TrackingSerializationContext { history: Vec::new() };
3776        let _result = serializer.partial_serialize(&mut context, new_buf_vec).unwrap();
3777        assert_eq!(context.history, vec![3, 2, 1]);
3778    }
3779}