Skip to main content

FetchObjectHeader

Struct FetchObjectHeader 

Source
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; see SubgroupIdEncoding
  • & 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: u8

Raw Serialization Flags byte, as decoded or as it is to be written.

§group_id: VarInt

Resolved absolute Group ID.

§subgroup_id: VarInt

Resolved absolute Subgroup ID.

§object_id: VarInt

Resolved absolute Object ID.

§publisher_priority: u8

Publisher 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: VarInt

Payload 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

Source

pub fn subgroup_id_encoding(&self) -> SubgroupIdEncoding

How this object’s Subgroup ID is carried, from the low two flag bits.

Source

pub fn has_object_id(&self) -> bool

Whether the Object ID is on the wire, rather than the prior object’s ID plus one.

Source

pub fn has_group_id(&self) -> bool

Whether the Group ID is on the wire, rather than the prior object’s.

Source

pub fn has_priority(&self) -> bool

Whether the Publisher Priority is on the wire, rather than the prior object’s.

Source

pub fn has_extensions(&self) -> bool

Whether an extensions block is on the wire.

Source

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.

Source

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.”

Source

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.

Source

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

Source§

fn clone(&self) -> FetchObjectHeader

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FetchObjectHeader

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for FetchObjectHeader

Source§

impl PartialEq for FetchObjectHeader

Source§

fn eq(&self, other: &FetchObjectHeader) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for FetchObjectHeader

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.