pub struct FetchObjectWriter {
prior_location: Option<(u64, u64)>,
prior_subgroup_id: Option<u64>,
prior_publisher_priority: Option<u8>,
}Expand description
Re-encodes resolved fetch frames onto one FETCH stream.
The exact inverse of FetchObjectReader, and it exists for one caller:
something that has read a stream and is writing a different stream from the
same frames. Removing a frame changes what the frames after it are read
against, and draft-17 Section 10.4.4.1 lets an Object leave out its Group
ID, Object ID, Subgroup ID and Priority and take the prior Object’s, so the
survivor that follows a removed run cannot keep its original bytes: a field
it left off has to appear, and a flag bit with it.
§Draft-17 states these fields, it does not delta them
A Group ID or Object ID that is on the wire here is the absolute value, not a difference — the deltas arrive at draft-18. What is stateful is the omission: no Group ID means the prior Object’s, and no Object ID means the prior Object’s plus one. That is enough to make removal a re-encode, and it is why this writer refuses nothing an Object can be: every identity has an encoding here, however the predecessor moved.
§Why this is not a general encoder
Every frame it writes came off a stream, so the caller holds the frame’s own
FetchObjectHeader alongside the resolved values, and that header is used
as the preference: wherever the original shape still says the same thing
against the new predecessor it is kept, so a stream with nothing removed is
reproduced byte for byte.
Fields§
§prior_location: Option<(u64, u64)>Group ID and Object ID of the last frame written, marker or Object.
prior_subgroup_id: Option<u64>Subgroup ID of the last actual Object written that had one.
prior_publisher_priority: Option<u8>Publisher Priority of the last actual Object written.
Implementations§
Source§impl FetchObjectWriter
impl FetchObjectWriter
Sourcepub fn new() -> Self
pub fn new() -> Self
A writer positioned before the first Object of a fetch stream, with no prior Object for anything to be encoded against.
Sourcepub fn header_for(
&self,
frame: &FetchObject,
) -> Result<FetchObjectHeader, CodecError>
pub fn header_for( &self, frame: &FetchObject, ) -> Result<FetchObjectHeader, CodecError>
The header that encodes frame against everything written so far.
Does not advance the writer — Self::write_object_header is the call
that does both.
§Errors
CodecError::InvalidField for an Object with neither a Subgroup ID
nor the Datagram bit, and for one with no Priority: both are frames no
draft-17 stream could carry, and inventing a value would put a different
Object on the wire than the one this was handed.
Sourcefn identity_fields(
&self,
frame: &FetchObject,
original: &FetchObjectHeader,
) -> Result<(Option<VarInt>, Option<VarInt>), CodecError>
fn identity_fields( &self, frame: &FetchObject, original: &FetchObjectHeader, ) -> Result<(Option<VarInt>, Option<VarInt>), CodecError>
The Group ID and Object ID fields, present only where leaving them off would say something else.
Both are absolute when written, so the choice is only whether to write them, and it is made in favour of the shape the frame arrived in: an Object that stated its Group ID keeps stating it even where the predecessor now shares it, which costs the same bytes it already cost.
Sourcefn subgroup_field(
&self,
frame: &FetchObject,
original: &FetchObjectHeader,
) -> Result<(u64, Option<VarInt>), CodecError>
fn subgroup_field( &self, frame: &FetchObject, original: &FetchObjectHeader, ) -> Result<(u64, Option<VarInt>), CodecError>
The Subgroup ID mode bits and the explicit field, if one is needed.
The frame’s own mode is tried first, so a run of Objects that inherited their Subgroup ID keeps inheriting it and its bytes do not move.
Sourcefn priority_field(
&self,
frame: &FetchObject,
original: &FetchObjectHeader,
) -> Result<Option<u8>, CodecError>
fn priority_field( &self, frame: &FetchObject, original: &FetchObjectHeader, ) -> Result<Option<u8>, CodecError>
The Publisher Priority field, or None when the predecessor already
carries it.
Sourcepub fn write_object_header(
&mut self,
frame: &FetchObject,
out: &mut impl BufMut,
) -> Result<FetchObjectHeader, CodecError>
pub fn write_object_header( &mut self, frame: &FetchObject, out: &mut impl BufMut, ) -> Result<FetchObjectHeader, CodecError>
Encode frame against everything written so far and advance.
Writes the header only. The payload is frame.header.payload_length
bytes and is the caller’s to copy, unchanged.
§Errors
CodecError::InvalidField for a frame with no encoding at all; the
writer is left untouched when this happens.
Sourcepub fn advance(&mut self, frame: &FetchObject)
pub fn advance(&mut self, frame: &FetchObject)
Record frame as the predecessor of whatever is written next.
Public because a re-emitting caller has a second way of putting a frame on the wire: when the framing it arrived in still encodes the same meaning against the frame before it, its own bytes are forwarded untouched — no header is produced and nothing is copied. The writer still has to move, or the frame after it is encoded against a predecessor one frame stale.
Trait Implementations§
Source§impl Clone for FetchObjectWriter
impl Clone for FetchObjectWriter
Source§fn clone(&self) -> FetchObjectWriter
fn clone(&self) -> FetchObjectWriter
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more