Skip to main content

AnyFetchObjectWriter

Struct AnyFetchObjectWriter 

Source
pub struct AnyFetchObjectWriter { /* private fields */ }
Expand description

Re-emitter for the frames of a fetch data stream, for any enabled draft.

The inverse of AnyFetchObjectReader, and it exists for one caller: a relay reading one fetch stream and writing another from the same frames, having removed some of them. Removing a frame changes what the frames behind it are encoded against, and on drafts 15-19 nearly every field of a fetch object is defined against the frame before it — draft-17 Section 10.4.4.1, Table 7: “Object ID is the prior Object’s ID plus one” — so a survivor following a removed run cannot keep its original bytes.

§How it is driven

One writer belongs to one stream, and reemit_object is called for every frame the caller forwards, in wire order, whether or not anything has been removed yet. That call is what moves the writer, so a forwarded frame it never saw leaves it a frame behind and re-encodes the next survivor against the wrong predecessor. A frame the caller elides is the one it is not called for — that is the whole of eliding.

§What it costs

Nothing on drafts 07-14, and on drafts 15-19 one header re-derivation per frame, which allocates only when the answer differs from the bytes that arrived. A stream with nothing removed from it therefore forwards every frame’s own bytes and copies no payload.

§Drafts 18 and 19 need the Group Order

Their Group ID is a difference whose sign the fetch’s Group Order decides, exactly as for AnyFetchObjectReader, and it is settled on the control plane rather than on the data stream. new takes it for that reason: the wrong order re-encodes without error onto groups walking the wrong way.

Implementations§

Source§

impl AnyFetchObjectWriter

Source

pub fn new( header: &AnyFetchHeader, group_order: AnyFetchGroupOrder, ) -> Result<Self, CodecError>

Create a writer for a stream with the given header, whose groups are written in group_order.

See the type’s own documentation for what the order is for and why it cannot be read off the stream. On drafts 07-17 the argument is ignored.

Returns CodecError::UnsupportedDraft for drafts not compiled in.

Source

pub fn draft(&self) -> DraftVersion

The draft this writer encodes.

Source

pub fn reemit_object( &mut self, frame: &AnyFetchFrame, raw: &[u8], out: &mut impl BufMut, ) -> Result<FetchReemit, CodecError>

Re-emit one forwarded fetch frame, re-encoding its framing against the frames actually forwarded before it, and advance.

frame came from AnyFetchObjectReader::read_object_frame on the stream being read; raw is that frame’s wire bytes. The return value says which bytes to forward, and the two answers are not symmetric: FetchReemit::Unchanged writes nothing and means raw is still correct, while FetchReemit::Reframed has written the whole frame to out and raw must not also be forwarded.

§raw need not be a complete frame

Any prefix is legal provided the whole framing is present — the framing being meta.wire_len - meta.payload_length bytes, which is a number the frame already carries. Everything behind it is copied byte-for-byte, however many bytes there are, and no length validation is performed. That is what lets a caller fix up the first chunk of a frame too large to buffer, where only the first chunk carries the framing at all.

§Errors

CodecError::UnsupportedDraft when frame was read off another draft’s stream.

CodecError::InvalidField when raw is shorter than the framing the frame declares, and when the frame has no encoding against the predecessor now in front of it — a Group ID that moves against the Group Order, an Object ID that does not advance, and the arithmetic overflows. The writer is left where it was in that case, so a caller that gives up on one frame and carries on is not also one frame out.

Trait Implementations§

Source§

impl Clone for AnyFetchObjectWriter

Source§

fn clone(&self) -> AnyFetchObjectWriter

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 AnyFetchObjectWriter

Source§

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

Formats the value using the given formatter. Read more

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.