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: VarIntThe 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: VarIntObject Payload Length. Always on the wire; the payload itself follows this header 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>
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.
Sourcepub fn subgroup_id_mode(&self) -> u8
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.
Sourcepub fn is_datagram(&self) -> bool
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.
Sourcepub fn decode(buf: &mut impl Buf) -> Result<Self, CodecError>
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.
Sourcepub fn encode(&self, buf: &mut impl BufMut) -> Result<(), CodecError>
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
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