Skip to main content

FetchObjectHeader

Struct FetchObjectHeader 

Source
pub struct FetchObjectHeader {
    pub serialization_flags: VarInt,
    pub group_id_delta: Option<VarInt>,
    pub subgroup_id: Option<VarInt>,
    pub object_id_delta: Option<VarInt>,
    pub publisher_priority: Option<u8>,
    pub properties: Option<Vec<u8>>,
    pub payload_length: VarInt,
}
Expand description

One Object on a draft-19 fetch stream, up to but not including its payload.

Draft-19 Section 11.4.4 rebuilt the fetch object. Earlier drafts wrote a fixed set of fields on every Object; draft-19 writes a Serialization Flags varint first, and the flags say which fields follow:

{
  Serialization Flags (vi64),
  [Group ID Delta (vi64),]
  [Subgroup ID (vi64),]
  [Object ID Delta (vi64),]
  [Publisher Priority (8),]
  [Properties (..),]
  Object Payload Length (vi64),
  [Object Payload (..),]
}

Every field is optional except the flags and the payload length, and an absent field means the same as the previous Object’s, not “zero” — the whole point of the layout is that a run of Objects in one group at one priority costs one byte of framing each. This type therefore holds what is on the wire and nothing more: the deltas, not the Group and Object IDs they resolve to. Resolving them needs the previous Object on the same stream and the FETCH’s Group Order, neither of which a single Object header knows, and Section 11.4.4 spells out the arithmetic a caller must apply:

  • The first Object MUST carry both deltas, and they are the absolute Group ID and Object ID.
  • Later on, a Group ID Delta moves the group by delta + 1 — forwards under Ascending Group Order and backwards under Descending — and restarts the Object ID from the Object ID Delta. With no Group ID Delta, the group is unchanged and the Object ID Delta is added to the previous Object’s ID; with no Object ID Delta either, the Object ID is the previous one plus one.

There is no Object Status field. Draft-19 Section 11.2.1.1 states that Object Status is present only on Objects delivered via a subscription and absent from Objects delivered via a FETCH, which is why this type has no counterpart to SubgroupObject::object_status and why a zero payload_length here is simply an Object with no payload.

Two Serialization Flags values name an End of Range indicator rather than an Object; Self::end_of_range reports which, and Section 11.4.4.2 gives the rules such a frame follows.

Fields§

§serialization_flags: VarInt

The raw Serialization Flags value, kept whole rather than split into booleans because it is also the field that names an End of Range indicator, and because re-encoding must reproduce the value the publisher chose.

§group_id_delta: Option<VarInt>

Group ID Delta, present when the flags set 0x08. Its meaning depends on the Object’s position in the stream and on the Group Order; see the type’s own documentation.

§subgroup_id: Option<VarInt>

An explicit Subgroup ID, present only when the two low flag bits are 0b11 and the Datagram bit is clear. The other three modes derive the Subgroup ID from the previous Object and put nothing on the wire.

§object_id_delta: Option<VarInt>

Object ID Delta, present when the flags set 0x04. Absent means the previous Object’s ID plus one.

§publisher_priority: Option<u8>

Publisher Priority, present when the flags set 0x10. Absent means the previous Object’s priority.

§properties: Option<Vec<u8>>

Raw properties bytes, excluding the byte-length prefix that precedes them on the wire, and None when the flags leave 0x20 clear.

Some(vec![]) and None are different frames: the first writes a zero length prefix, the second writes nothing at all. Opaque, like the property blocks on the subgroup and datagram forms — draft-19 Section 11.4.4 defines the field as the Object Properties structure of Section 11.2.1.2, and these bytes are re-emitted verbatim.

§payload_length: VarInt

Object Payload Length. Always on the wire; the payload itself follows this header and is not held here.

Implementations§

Source§

impl FetchObjectHeader

Source

pub fn flags(&self) -> u64

The Serialization Flags as a plain integer.

Source

pub fn end_of_range(&self) -> Option<FetchEndOfRange>

Which End of Range indicator this is, or None for an ordinary Object.

Draft-19 Section 11.4.4, Table 7 gives the two indicators their own Serialization Flags values rather than a flag bit, so this is an equality test on the whole field and not a mask.

An indicator uses the same two positions on the wire an ordinary Object uses for its deltas, but Section 11.4.4.2 reads them as the absolute Group ID and Object ID of the end of the range. They are still reached through Self::group_id_delta and Self::object_id_delta, since those are the fields the wire has; what changes is what they mean, and this is how a caller knows which reading applies.

Source

pub fn subgroup_id_mode(&self) -> u8

The two-bit Subgroup ID mode, flags & 0x03.

0b00 = the Subgroup ID is zero; 0b01 = the previous Object’s Subgroup ID; 0b10 = the previous Object’s Subgroup ID plus one; 0b11 = an explicit field is present. Draft-19 Section 11.4.4.1 assigns all four, unlike the subgroup stream header’s reserved 0b11.

Meaningless when Self::is_datagram is true: such an Object has no Subgroup ID and the section says the subscriber MUST ignore these bits.

Source

pub fn is_datagram(&self) -> bool

true when the flags set 0x40, marking an Object whose Forwarding Preference is Datagram. Such an Object has no Subgroup ID at all, so the Subgroup ID mode bits carry no meaning and no Subgroup ID field is on the wire whatever they say.

Source

pub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>

Decode one fetch object header, leaving the payload in buf.

Errors with CodecError::InvalidField for a Serialization Flags value draft-19 Section 11.4.4 does not define, and with CodecError::UnexpectedEnd or a varint error when the buffer runs out mid-field.

The flags are validated before any field is read, because they are what says where the fields are: decoding an undefined value would mean picking a layout the draft never described and then consuming a plausible number of bytes under it.

Source

pub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>

Serialize the header, refusing one whose fields disagree with its own Serialization Flags.

Errors with CodecError::InvalidField when the flags are a value draft-19 does not define, and when any optional field is present while its flag is clear or absent while its flag is set. Checked before any byte is written, so a refused header leaves buf untouched.

Fallible for the same reason DatagramHeader::encode_checked is: the flags decide the framing, so writing them as the authority and dropping whatever they do not cover is silent data loss. A Group ID Delta held with the 0x08 bit clear is not written, the reader takes the Object as belonging to the previous Object’s group, and nothing about the resulting stream looks wrong. The mirror case is worse: a flag set with no value behind it would have to invent one, and an invented Object ID Delta of zero is a real Object ID.

Nothing here checks the deltas against the previous Object — that no Object other than the first may reference a prior Object that does not exist, for one. A single header has no way to see that, and this type deliberately does not carry stream state.

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, <T as TryFrom<U>>::Error>

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.