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