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