pub struct FetchObjectHeader {
pub serialization_flags: VarInt,
pub group_id: Option<VarInt>,
pub subgroup_id: Option<VarInt>,
pub object_id: Option<VarInt>,
pub publisher_priority: Option<u8>,
pub properties: Vec<u8>,
pub payload_length: VarInt,
}Expand description
One object on a draft-17 fetch stream, without its payload.
Draft-17 Section 10.4.4, Figure 27:
{
Serialization Flags (vi64),
[Group ID (vi64),]
[Subgroup ID (vi64),]
[Object ID (vi64),]
[Publisher Priority (8),]
[Properties (..),]
Object Payload Length (vi64),
[Object Payload (..),]
}§Why the fields are optional
Every bracketed field above is one the Serialization Flags may leave off the wire, and leaving it off does not mean the object lacks it — Table 8 gives each absent field a meaning drawn from the object before it on the stream (“Object ID is the prior Object’s ID plus one”, “Group ID is the prior Object’s Group ID”, “Priority is the prior Object’s Priority”), and Table 7 does the same for the Subgroup ID. A single object’s bytes therefore do not determine its Location; only the run of objects before it does.
So this type reports presence rather than inventing a value: None means
the wire did not say, and resolving it is the job of a caller that has
been following the stream. Self::references_prior_object is how such a
caller learns whether resolution is even needed, and it is what makes the
draft’s rule about the first object checkable: “If the first Object in the
FETCH response uses a flag that references fields in the prior Object, the
Subscriber MUST close the session with a PROTOCOL_VIOLATION.”
§What draft-17 changed
Through draft-13 a fetch object spelled out Group ID, Subgroup ID, Object ID
and Publisher Priority on every object and carried an Object Status beside a
zero-length payload. Draft-17 has neither habit: the flags replace the four
unconditional fields, and there is no status field at all — Section 10.2.1.1
says the Object Status “is only present in objects that are delivered via a
SUBSCRIPTION, and is absent in Objects delivered via a FETCH”. A zero
payload_length here is simply an object with no bytes.
Fields§
§serialization_flags: VarIntThe Serialization Flags varint, verbatim.
Kept whole rather than split into the fields below because it says more
than which fields are present: the two low bits pick between four
Subgroup ID meanings that share one absent field, and the values 0x8C
and 0x10C are not bit patterns at all. It is also the authority
Self::encode writes from.
group_id: Option<VarInt>Group ID, when the flags put it on the wire.
subgroup_id: Option<VarInt>Subgroup ID, present only under SUBGROUP mode 0x03. The other three
modes leave it off the wire with a meaning of their own, which
Self::subgroup_id_mode reports.
object_id: Option<VarInt>Object ID, when the flags put it on the wire.
publisher_priority: Option<u8>Publisher priority, when the flags put it on the wire.
properties: Vec<u8>Raw properties bytes, excluding the byte-length prefix that precedes them on the wire. Present only when the flags set the PROPERTIES bit (0x20), and empty otherwise — the bit is what puts the block on the wire, so contents held here with the bit clear are not written.
Opaque, exactly as DatagramHeader::properties is: the prefix and
these bytes are re-emitted verbatim.
payload_length: VarIntDeclared byte length of the payload that follows this header.
Implementations§
Source§impl FetchObjectHeader
impl FetchObjectHeader
Sourcepub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>
pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>
Decode one fetch object’s framing, stopping after the Object Payload Length.
The payload itself is left in buf — payload_length says how many
bytes of it there are, and a caller streaming objects usually wants to
forward or skip them rather than copy them.
Errors with CodecError::InvalidField on a Serialization Flags value
draft-17 does not define. Section 10.4.4 reads the value as a bit set
only “when less than 128”, names 0x8C and 0x10C as the two larger
values that mean anything, and then says of the rest: “Any other value is
a PROTOCOL_VIOLATION.”
Sourcepub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
Serialize the framing, stopping after the Object Payload Length.
The payload is the caller’s to append, matching Self::decode leaving
it in the buffer.
Fallible, unlike the other encoders here, because the flags and the
fields can disagree in a way no default resolves. DatagramHeader can
write a priority the type byte demands and the value omits, because
draft-17 has a default priority to write; a Group ID the flags demand and
the value omits has no such stand-in — every candidate is a Location this
object does not have. Writing nothing there instead would slide the next
field into its place and desynchronize the whole stream, which no reader
downstream could detect, let alone repair.
Errors with CodecError::InvalidField, before any byte is written, on:
- a Serialization Flags value draft-17 does not define, the set
Self::decoderefuses; - a field the flags announce and the value leaves
None; - a field the value supplies and the flags do not announce, including
non-empty
propertieswith the PROPERTIES bit clear — silently dropping it would emit an object stripped of metadata that the caller believes it sent.
Sourcepub fn end_of_range(&self) -> Option<EndOfRange>
pub fn end_of_range(&self) -> Option<EndOfRange>
The end-of-range marker this object is, if it is one.
None for every flags value below 128, which is every object that
carries content.
Sourcepub fn subgroup_id_mode(&self) -> u64
pub fn subgroup_id_mode(&self) -> u64
The SUBGROUP mode: serialization_flags & 0x03, per draft-17
Section 10.4.4.1 Table 7.
0x00 = the Subgroup ID is zero; 0x01 = it is the prior object’s;
0x02 = it is the prior object’s plus one; 0x03 = it is present in
Self::subgroup_id.
Meaningless when Self::is_datagram holds — Section 10.4.4.1 says of
the DATAGRAM bit that the subscriber “MUST ignore the bits” — and this
reports the raw two bits regardless, so check that first.
Sourcepub fn is_datagram(&self) -> bool
pub fn is_datagram(&self) -> bool
Whether the DATAGRAM bit (0x40) is set: the object was forwarded with an Object Forwarding Preference of Datagram and so has no Subgroup ID at all.
Sourcepub fn has_properties(&self) -> bool
pub fn has_properties(&self) -> bool
Whether the flags set the PROPERTIES bit (0x20), which is what puts
Self::properties on the wire.
Sourcepub fn references_prior_object(&self) -> bool
pub fn references_prior_object(&self) -> bool
Whether resolving this object’s fields requires the object before it on the stream.
True when any of the Group ID, Object ID or Priority fields is absent —
draft-17 Section 10.4.4.1 Table 8 defines each absent field in terms of
“the prior Object” — or when the SUBGROUP mode names the prior object’s
Subgroup ID or that ID plus one. Mode 0x00 is not such a case: it fixes
the Subgroup ID at zero without consulting anything.
This is the predicate Section 10.4.4 makes load-bearing: “If the first Object in the FETCH response uses a flag that references fields in the prior Object, the Subscriber MUST close the session with a PROTOCOL_VIOLATION.” A single object’s bytes cannot tell whether it is the first, so the decoder cannot enforce that; a caller reading the stream can, and this is what it asks.
False for both end-of-range markers. Section 10.4.4.2 fixes their fields outright — “the Group ID and Object ID fields are present. Subgroup ID, Priority and Properties are not present” — so a marker inherits nothing, and the section’s own phrase “the last serialized Object, if any” allows one to open a response.
Trait Implementations§
Source§impl Clone for FetchObjectHeader
impl Clone for FetchObjectHeader
Source§fn clone(&self) -> FetchObjectHeader
fn clone(&self) -> FetchObjectHeader
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more