pub struct FetchObjectHeader {
pub serialization_flags: u8,
pub group_id: VarInt,
pub subgroup_id: VarInt,
pub object_id: VarInt,
pub publisher_priority: u8,
pub extension_headers: Vec<u8>,
pub payload_length: VarInt,
pub object_status: Option<ObjectStatus>,
}Expand description
One object on a draft-15 fetch stream, without its payload.
Draft-15 Section 10.4.4 gives fetch objects a leading Serialization Flags
byte that says which of the object’s fields are on the wire; every field it
omits is taken from, or counted from, the object before it on the same
stream. An object therefore cannot be decoded on its own, and the fields
below are the resolved absolute values rather than whatever the wire spelled
out — reading them needs the running state a FetchObjectReader carries.
serialization_flags is kept beside the resolved values so that an object
re-encodes to the bytes it was decoded from. One object has as many
encodings as there are flag bytes that resolve to it, and choosing one on
the caller’s behalf would rewrite a stream a relay is meant to forward
unchanged.
The bits, from Section 10.4.4, Tables 7 and 8:
& 0x03: how the Subgroup ID is carried; seeSubgroupIdEncoding& 0x04: Object ID field present, else the prior object’s ID plus one& 0x08: Group ID field present, else the prior object’s Group ID& 0x10: Publisher Priority field present, else the prior object’s& 0x20: Extensions field present& 0xc0: unassigned, and Table 8 makes either bit a protocol violation
The payload is deliberately not part of this type: an object’s declared
length is the last thing before its bytes, so a caller that forwards
payloads verbatim can read the framing and then move payload_length bytes
without ever copying them.
Fields§
§serialization_flags: u8Raw Serialization Flags byte, as decoded or as it is to be written.
group_id: VarIntResolved absolute Group ID.
subgroup_id: VarIntResolved absolute Subgroup ID.
object_id: VarIntResolved absolute Object ID.
publisher_priority: u8Publisher priority for delivery ordering.
extension_headers: Vec<u8>Raw extension-header bytes, excluding the byte-length prefix that
precedes them on the wire. Empty when the flags do not set the
extensions bit, or when the block is present but zero-length. Opaque:
FetchObjectReader::write_object_header re-emits the prefix and these
bytes verbatim.
payload_length: VarIntPayload length as encoded on the wire. Zero when the object is a status-only object.
object_status: Option<ObjectStatus>Object status; Some when payload_length == 0.
Section 10.4.4: “The Object Status field is only present if the Object
Payload Length is zero.” Typed to the statuses draft-15 assigns for the
same reason SubgroupObject::object_status is: the field cannot hold
a code the draft leaves unassigned, so the encoder needs no check and
cannot emit an object the decoder would refuse.
None on a zero-length object means the same as
ObjectStatus::Normal and encodes as it; the wire field is not
optional once payload_length is zero.
Implementations§
Source§impl FetchObjectHeader
impl FetchObjectHeader
Sourcepub fn subgroup_id_encoding(&self) -> SubgroupIdEncoding
pub fn subgroup_id_encoding(&self) -> SubgroupIdEncoding
How this object’s Subgroup ID is carried, from the low two flag bits.
Sourcepub fn has_object_id(&self) -> bool
pub fn has_object_id(&self) -> bool
Whether the Object ID is on the wire, rather than the prior object’s ID plus one.
Sourcepub fn has_group_id(&self) -> bool
pub fn has_group_id(&self) -> bool
Whether the Group ID is on the wire, rather than the prior object’s.
Sourcepub fn has_priority(&self) -> bool
pub fn has_priority(&self) -> bool
Whether the Publisher Priority is on the wire, rather than the prior object’s.
Sourcepub fn has_extensions(&self) -> bool
pub fn has_extensions(&self) -> bool
Whether an extensions block is on the wire.
Sourcepub fn references_prior_object(&self) -> bool
pub fn references_prior_object(&self) -> bool
Whether any of this object’s fields is taken from the object before it on the stream.
Draft-15 Section 10.4.4: “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 flags do so — two of the Subgroup ID encodings, and the cleared state of the Object ID, Group ID and Priority bits, each of which means “the prior object’s”. The extensions bit does not: it is present or it is not, and nothing is inherited either way.
Sourcepub fn status(&self) -> ObjectStatus
pub fn status(&self) -> ObjectStatus
The status this object resolves to.
Section 10.4.4: “The Object Status field is only present if the Object
Payload Length is zero.” An object declaring a length is therefore
ObjectStatus::Normal whatever Self::object_status holds, on the
reading Section 10.2.1.1 gives Normal: “This status is implicit for any
non-zero length object.”
Sourcepub fn extensions_permitted(&self) -> bool
pub fn extensions_permitted(&self) -> bool
Whether this object’s status is allowed to carry the extension headers it has.
The fetch half of the rule SubgroupObject::extensions_permitted
answers, and the same one: Section 10.4.4 builds a fetch object’s
Extensions field out of the structure Section 10.2.1.2 defines, and that
section is where the rule sits — “Any Object with status Normal can have
extension headers. If an endpoint receives extension headers on Objects
with status that is not Normal, it MUST close the session with a
PROTOCOL_VIOLATION.”
Draft-15 is the only draft where a fetch object can state this
violation, which is why no counterpart to this exists on drafts 16 and
later rather than one that is always true. Section 10.4.4 gives this
draft’s fetch object an Object Status field — “The Object Status field
is only present if the Object Payload Length is zero” — and its
extensions bit, Table 8’s 0x20, is independent of every other flag, so
the two can appear together. Drafts 16 and later remove the field
outright, draft-16 Section 10.2.1.1: “The Object Status is a field that
is only present in objects that are delivered via a SUBSCRIPTION, and is
absent in Objects delivered via a FETCH.” A fetch object there has no
status to disagree with, so the rule has nothing to bite on.
FetchObjectReader reports this rather than refusing it, for the
reason SubgroupObject::extensions_permitted sets out: the frame is
well formed and merely non-conforming, and a reader that refused it
could not reproduce a capture containing one.
Sourcepub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
Serialize this Object’s framing, writing only the fields its own Serialization Flags announce.
The inverse of FetchObjectReader::read_object_header, and the reason
it is fallible where the subgroup form’s is not: this type holds every
field resolved, so the flags rather than the values decide what goes on
the wire. A Group ID held with the 0x08 bit clear is not written and
the reader takes the Object as sharing its predecessor’s group — which
is silent data loss when the two differ, and correct when they do not.
Nothing here can tell those apart, so the caller settles it by choosing
the flags, and FetchObjectWriter is what chooses them against a
predecessor.
§Errors
CodecError::InvalidField for a flags byte with either of the two
bits Section 10.4.4 leaves unassigned, which is the same value
FetchObjectReader::read_object_header refuses to read — the field is
one fixed byte and not a variable-length integer, so 0x40 and 0x80 are
not wider spellings of anything.
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