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 extensions: Option<Vec<u8>>,
pub payload_length: VarInt,
}Expand description
One Object as it is framed on a draft-16 fetch stream, before any field is resolved against the Object before it.
Draft-16 Section 10.4.4 Figure 31 gives the layout: a Serialization Flags
varint, then Group ID, Subgroup ID, Object ID, Publisher Priority and
Extensions, each present only when the flags say so, then an Object Payload
Length and the payload itself. Every optional field here is Some exactly
when its bytes were on the wire, so Self::encode can put back the same
bytes Self::decode took off — including the difference between an absent
extensions block and a present, zero-length one.
The payload is not part of this struct: payload_length bytes follow it on
the stream. That mirrors SubgroupObjectMeta, and it is what lets a relay
that forwards bytes verbatim read the framing without copying the payload.
Two things separate this from the fetch object of drafts 07-13. There is no
Object Status field — Section 10.2.1.1 says the status “is only present in
objects that are delivered via a SUBSCRIPTION, and is absent in Objects
delivered via a FETCH” — so a zero payload_length is simply an empty
object, with no status varint behind it. And the fields that are present are
absolute: the flags decide presence, and Table 5 and Table 6 decide what an
absent field inherits, but a field that is on the wire carries its own value
rather than a delta. Draft-16 spells “Object ID Delta” out by name where it
means one, on subgroup streams; Figure 31 says “Object ID”.
Resolving the absent fields needs the Object before this one, which a single
header does not have. FetchObjectReader carries that state.
Fields§
§serialization_flags: VarIntSerialization Flags exactly as they appeared on the wire: a flag word
below 128, or one of the FetchEndOfRange markers.
group_id: Option<VarInt>Group ID, when the flags put it on the wire.
subgroup_id: Option<VarInt>Subgroup ID, present only under FetchSubgroupMode::Present.
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.
extensions: Option<Vec<u8>>Raw extension-header bytes, excluding the byte-length prefix that
precedes them on the wire, and None when the flags carry no extensions
block at all. Opaque: Self::encode re-emits the prefix and these
bytes verbatim. The block’s own shape is the one Section 10.2.1.2
defines for every draft-16 object.
payload_length: VarIntDeclared Object Payload Length. The payload follows on the stream and is not held here.
Implementations§
Source§impl FetchObjectHeader
impl FetchObjectHeader
Sourcepub fn end_of_range(&self) -> Option<FetchEndOfRange>
pub fn end_of_range(&self) -> Option<FetchEndOfRange>
The Table 4 marker this object is, or None when its Serialization
Flags are an ordinary flag word.
Sourcepub fn is_datagram(&self) -> bool
pub fn is_datagram(&self) -> bool
Bit 0x40: the Object’s Forwarding Preference is Datagram, so it has no Subgroup ID.
Draft-16 Section 10.4.4.1 requires the publisher to set this bit for such
an Object, says it SHOULD then zero the two least significant bits, and
requires the subscriber to ignore them — so a Subgroup ID is not read
even when those bits spell FetchSubgroupMode::Present. Ignoring them
is a framing decision, not a cosmetic one: reading a Subgroup ID there
would consume a varint that belongs to the next field.
Never true for a FetchEndOfRange marker, whose value is not a flag
word.
Sourcepub fn subgroup_mode(&self) -> FetchSubgroupMode
pub fn subgroup_mode(&self) -> FetchSubgroupMode
The Table 5 reading of the two least significant bits.
Answers FetchSubgroupMode::Zero for a FetchEndOfRange marker and
for a Datagram-forwarded Object, neither of which has a Subgroup ID on
the wire: Section 10.4.4.2 lists Subgroup ID among the fields an End of
Range does not carry, and Section 10.4.4.1 says a Datagram Object has
none at all.
Sourcepub fn has_group_id(&self) -> bool
pub fn has_group_id(&self) -> bool
Whether a Group ID field is on the wire (bit 0x08).
Always true for a FetchEndOfRange marker: Section 10.4.4.2 says both
the Group ID and the Object ID fields are present.
Sourcepub fn has_subgroup_id(&self) -> bool
pub fn has_subgroup_id(&self) -> bool
Whether a Subgroup ID field is on the wire, which is
FetchSubgroupMode::Present and nothing else.
Sourcepub fn has_object_id(&self) -> bool
pub fn has_object_id(&self) -> bool
Whether an Object ID field is on the wire (bit 0x04).
Always true for a FetchEndOfRange marker, per Section 10.4.4.2.
Sourcepub fn has_priority(&self) -> bool
pub fn has_priority(&self) -> bool
Whether a Publisher Priority byte is on the wire (bit 0x10).
Never true for a FetchEndOfRange marker: Section 10.4.4.2 lists
Priority among the fields it does not carry.
Sourcepub fn has_extensions(&self) -> bool
pub fn has_extensions(&self) -> bool
Whether an Extensions block is on the wire (bit 0x20).
Never true for a FetchEndOfRange marker, per Section 10.4.4.2.
Sourcepub fn references_prior_object(&self) -> bool
pub fn references_prior_object(&self) -> bool
Whether these flags read any field off the Object before this one.
Draft-16 Section 10.4.4.1 closes the section on flags with: “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.” Four of the readings do that — an absent Group ID, Object ID or Priority each names the prior Object in Table 5 or Table 6, as do the two middle Subgroup ID modes.
FetchSubgroupMode::Zero does not: it states a value outright. Nor
does an absent Extensions block, which means the Object has none rather
than the ones before it. A FetchEndOfRange marker references nothing
either — its Group ID and Object ID are always present, and Section
10.4.4.2 gives it no Priority or Extensions to inherit.
FetchObjectReader::resolve refuses the first Object of a stream when
this is true of a field it would have to produce a value for. It is
exposed separately because the draft’s rule is wider than that: it also
covers an absent Priority, for which Section 11.1.1.1 supplies a default
that makes resolution possible anyway.
Sourcepub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
Encode the object’s framing, refusing a struct that disagrees with its own Serialization Flags.
The flags are the authority on which fields are on the wire, so a field
that is Some while its flag is clear has nowhere to go, and one that is
None while its flag is set leaves a hole the reader would fill from the
bytes of the next field. Either way the result is a stream
Self::decode cannot read back as what was handed in, so both are
refused here.
Errors with CodecError::InvalidField on any such disagreement, and on
a Serialization Flags value at or above 128 that Table 4 does not assign,
before a single byte is written — a refused object leaves buf untouched
rather than half an object the next read would run into.
The payload is not written: payload_length bytes of it belong on the
stream immediately after these.
Sourcepub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>
pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>
Decode one object’s framing, leaving buf positioned at its payload.
Errors with CodecError::InvalidField when Serialization Flags is at
or above 128 and is not one of the two values Table 4 assigns — draft-16
Section 10.4.4 makes any other such value a PROTOCOL_VIOLATION, and there
is no way to guess which fields follow it.
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