Trait packet::serialize::NestedPacketBuilder
source · pub trait NestedPacketBuilder {
// Required methods
fn try_constraints(&self) -> Option<PacketConstraints>;
fn serialize_into<B: TargetBuffer>(&self, buffer: &mut B);
// Provided methods
fn encapsulate<O: NestedPacketBuilder>(self, outer: O) -> Nested<Self, O>
where Self: Sized { ... }
fn with_size_limit(self, limit: usize) -> LimitedSizePacketBuilder<Self>
where Self: Sized { ... }
}
Expand description
One or more nested PacketBuilder
s.
A NestedPacketBuilder
represents one or more PacketBuilder
s nested
inside of each other. Two NestedPacketBuilder
s, a
and b
, can be
composed by calling a.encapsulate(b)
. The resulting NestedPacketBuilder
has a header comprising b
’s header followed by a
’s header, and has a
footer comprising a
’s footer followed by b
’s footer. It also has minimum
and maximum body length requirements which are the composition of those of
a
and b
. See encapsulate
for more details.
Required Methods§
sourcefn try_constraints(&self) -> Option<PacketConstraints>
fn try_constraints(&self) -> Option<PacketConstraints>
Gets the constraints for this NestedPacketBuilder
.
If constraints
returns None
, it means that a valid
PacketConstraints
cannot be constructed. Since
NestedPacketBuilder
s can be nested, multiple valid
NestedPacketBuilder
s can nest to create an invalid
NestedPacketBuilder
. This can happen if an inner
NestedPacketBuilder
’s headers and footers take up more space than an
outer NestedPacketBuilder
’s maximum body length, so the maximum body
length of this NestedPacketBuilder
is technically negative. It can
also happen if the header and footer lengths, when summed, overflow
usize
. In either case, the PacketConstraints
type cannot represent
the constraints, and no body exists which would satisfy those
constraints (a satisfying body would need to have negative length).
Thus, the correct behavior is to interpret a None
value as implying
that constraints are violated.
If constraints
returns None
, the caller must not call
serialize_into
, or risk unspecified behavior (including possibly a
panic).
sourcefn serialize_into<B: TargetBuffer>(&self, buffer: &mut B)
fn serialize_into<B: TargetBuffer>(&self, buffer: &mut B)
Serializes this NestedPacketBuilder
into a buffer.
serialize_into
takes a buffer containing a body, and serializes this
NestedPacketBuilder
’s headers and footers before and after that body
respectively. When serialize_into
returns, the buffer’s body has been
expanded to include the newly-serialized headers and footers.
If the provided body is smaller than this NestedPacketBuilder
’s
minimum body length requirement, serialize_into
will add padding after
the body in order to meet that requriement. If this
NestedPacketBuilder
comprises multiple other NestedPacketBuilder
s
with their own minimum body length requirements, then internal padding
may be added between footers in order to meet those requirements. In
particular, padding is always added after the body of the packet with
that requirement (as opposed to after the body of an encapsulated
packet).
Callers should not add their own post-body padding! The minimum body
length requirement might come from a NestedPacketBuilder
which is not
the innermost one, in which case padding belongs after at least one of
the footers, and adding padding directly after the body would be
incorrect. As described in the previous paragraph, serialize_into
will
take care of putting padding in the right place.
Security
Any added padding will be zeroed in order to ensure that the contents of another packet previously stored in the same buffer do not leak.
Panics
May panic if buffer
doesn’t have enough prefix and suffix space to
hold the headers and footers. In particular, if this
NestedPacketBuilder
has PacketConstraints
c
, then buffer
must
satisfy the following requirements:
buffer.prefix_len() >= c.header_len()
buffer.suffix_len() >= c.footer_len()
buffer.len() <= c.max_body_len()
- If
padding = c.min_body_len().saturating_sub(buffer.len())
, thenbuffer.suffix_len() >= padding + c.footer_len()
Note that the PacketConstraints
type has certain invariants that make
it easier for implementers to satisfy these preconditions.
serialize_into
may exhibit unspecified behavior (including possibly
panicking) if self.try_constraints()
returns None
. In order to avoid
a panic, the caller must call that method first, and only call
serialize_into
if it returns Some
.
Provided Methods§
sourcefn encapsulate<O: NestedPacketBuilder>(self, outer: O) -> Nested<Self, O>where
Self: Sized,
fn encapsulate<O: NestedPacketBuilder>(self, outer: O) -> Nested<Self, O>where Self: Sized,
Encapsulates this NestedPacketBuilder
inside of another one.
If a
and b
are NestedPacketBuilder
s with PacketConstraints
ac
and bc
, then a.encapsulate(b)
produces a NestedPacketBuilder
with the following properties:
- Its header is equivalent to
b
’s header followed bya
’s header, and has lengthbc.header_len() + ac.header_len()
- Its footer is equivalent to
a
’s footer followed byb
’s footer, and has lengthac.footer_len() + bc.footer_len()
- Its minimum body length requirement is
core::cmp::max(ac.min_body_len(), bc.min_body_len() - (ac.header_len() + ac.footer_len()))
- Its maximum body length requirement is
core::cmp::min(ac.max_body_len(), bc.max_body_len() - (ac.header_len() + ac.footer_len()))
Note that a
and b
having valid PacketConstraints
does not imply
that a.encapsulate(b)
will as well. This could be for one of the
following reasons:
b
has a maximum body length requirement which is exceeded bya
’s headers and footers alone (without considering further space occupied by a body)b
has a maximum body length requirement which is exceeded by the sum ofa
’s header and footers anda
’s minimum body length requirement- The
PacketConstraints
would have values that overflowusize
, such asb
’s header length plusa
’s header length
sourcefn with_size_limit(self, limit: usize) -> LimitedSizePacketBuilder<Self>where
Self: Sized,
fn with_size_limit(self, limit: usize) -> LimitedSizePacketBuilder<Self>where Self: Sized,
Constructs a new NestedPacketBuilder
with an additional size limit
constraint
The returned NestedPacketBuilder
will have a maximum body length
constraint equal to the minimum of its original maximum body length
constraint and limit
.