Skip to main content

BufferedEncodeEngine

Struct BufferedEncodeEngine 

Source
pub struct BufferedEncodeEngine<C, H> { /* private fields */ }
Expand description

Reusable buffered encoding engine for codec-backed encoders.

The engine owns the low-level codec and hook object. It keeps the common buffered encoding loop private: input-index validation, output-capacity checks, input consumption, output progress, and crate::TranscodeStatus reporting.

Use this type to build a streaming encoder over a one-value Codec. The engine does not allocate output. It repeatedly asks hooks to plan one input value, verifies that the caller-provided output slice can hold that plan, and then lets the hooks write the value. If the next value would not fit, the engine returns crate::TranscodeStatus::NeedOutput without consuming that value; the caller can provide a larger or fresh output buffer and resume with the returned input index.

For the common strict policy that simply wraps codec errors, use crate::CodecBufferedEncoder. Use BufferedEncodeEngine directly when the encode policy needs custom planning, replacement, skipped values, or finish-time output.

§Example

use core::{
    convert::Infallible,
    num::NonZeroUsize,
};
use qubit_codec::{
    BufferedEncodeEngine,
    BufferedEncodeHooks,
    Codec,
    CodecEncodeError,
    EncodeContext,
    EncodePlan,
    TranscodeStatus,
};

#[derive(Clone, Copy)]
struct ByteCodec;

unsafe impl Codec for ByteCodec {
    type Value = u8;
    type Unit = u8;
    type DecodeError = Infallible;
    type EncodeError = Infallible;

    fn min_units_per_value(&self) -> NonZeroUsize {
        NonZeroUsize::MIN
    }

    fn max_units_per_value(&self) -> NonZeroUsize {
        NonZeroUsize::MIN
    }

    unsafe fn decode_unchecked(
        &self,
        input: &[u8],
        index: usize,
    ) -> Result<(u8, NonZeroUsize), Self::DecodeError> {
        Ok((input[index], NonZeroUsize::MIN))
    }

    unsafe fn encode_unchecked(
        &self,
        value: &u8,
        output: &mut [u8],
        index: usize,
    ) -> Result<usize, Self::EncodeError> {
        output[index] = *value;
        Ok(1)
    }
}

struct StrictHooks;

impl BufferedEncodeHooks<ByteCodec> for StrictHooks {
    type Error = CodecEncodeError<Infallible>;
    type PlanAction = ();

    fn prepare_encode(
        &mut self,
        codec: &ByteCodec,
        _value: &u8,
        _input_index: usize,
    ) -> Result<EncodePlan<()>, Self::Error> {
        Ok(EncodePlan::new(codec.max_units_per_value().get(), ()))
    }

    unsafe fn write_encode(
        &mut self,
        codec: &ByteCodec,
        context: EncodeContext<'_, u8, u8>,
        _plan: EncodePlan<()>,
    ) -> Result<usize, Self::Error> {
        unsafe {
            codec.encode_unchecked(context.input_value, context.output, context.output_index)
        }
        .map_err(|error| CodecEncodeError::encode(error, context.input_index))
    }

    fn invalid_input_index(
        &mut self,
        _codec: &ByteCodec,
        index: usize,
        input_len: usize,
    ) -> Self::Error {
        CodecEncodeError::invalid_input_index(index, input_len)
    }

    fn invalid_output_index(
        &mut self,
        _codec: &ByteCodec,
        index: usize,
        output_len: usize,
    ) -> Self::Error {
        CodecEncodeError::invalid_output_index(index, output_len)
    }
}

let mut engine = BufferedEncodeEngine::new(ByteCodec, StrictHooks);
let input = [1_u8, 2, 3];
let mut output = [0_u8; 2];

let progress = engine.transcode(&input, 0, &mut output, 0)?;
match progress.status() {
    TranscodeStatus::Complete => unreachable!("output is intentionally short"),
    TranscodeStatus::NeedOutput { output_index, .. } => {
        assert_eq!(2, output_index);
        assert_eq!([1, 2], output);
        // Write out `output[..output_index]`, then resume at
        // `progress.read()` with fresh output capacity.
    }
    TranscodeStatus::NeedInput { .. } => unreachable!("encoders do not read encoded input"),
}

§Type Parameters

  • C: Low-level codec used by the engine.
  • H: Policy hook object used by the engine.

Implementations§

Source§

impl<C, H> BufferedEncodeEngine<C, H>
where C: Codec, H: BufferedEncodeHooks<C>,

Source

pub const fn new(codec: C, hooks: H) -> Self

Creates a buffered encoder engine.

§Parameters
  • codec: Low-level codec used for one-value encoding.
  • hooks: Policy hooks used for planning and writing values.
§Returns

Returns a buffered encoder engine.

Source

pub fn max_output_len(&self, input_len: usize) -> Result<usize, CapacityError>

Returns a conservative upper bound for output units needed for input_len values.

§Parameters
  • input_len: Number of input values the caller plans to encode.
§Returns

Returns a conservative upper bound, or a capacity error on arithmetic overflow.

Source

pub fn max_finish_output_len(&self) -> usize

Returns the maximum output units emitted by finishing hook-owned state.

§Returns

Returns the hook-provided final output bound.

Source

pub fn reset(&mut self)

Resets hook-owned state.

§Parameters
  • self: Encoder instance whose hook state is reset.
§Returns

Returns unit ().

Source

pub fn transcode( &mut self, input: &[C::Value], input_index: usize, output: &mut [C::Unit], output_index: usize, ) -> Result<TranscodeProgress, H::Error>

Encodes values into a caller-provided output buffer.

The engine stops before consuming the next input value when the current output buffer does not satisfy that value’s planned capacity bound.

§Parameters
  • input: Complete input value slice visible to the encoder.
  • input_index: Absolute input value index where encoding starts.
  • output: Complete output unit slice visible to the encoder.
  • output_index: Absolute output unit index where writing starts.
§Returns

Returns progress describing input values consumed, output units written, and why encoding stopped.

§Errors

Returns hook errors when input_index is outside input, when output_index is outside output, or when hook planning or writing rejects a value.

Source

pub fn finish( &mut self, output: &mut [C::Unit], output_index: usize, ) -> Result<usize, FinishError<H::Error>>

Finishes hook-owned output after EOF.

The engine owns no final output state itself. Hook implementations may finish their own retained state and emit final output after the caller has supplied all input values. The caller must provide enough output capacity for BufferedEncodeEngine::max_finish_output_len.

§Parameters
  • output: Complete output unit slice visible to the encoder.
  • output_index: Absolute output unit index where writing starts.
§Returns

Returns the number of units written by finalization.

§Errors

Returns FinishError when the caller provides invalid or insufficient output capacity, or when hook finalization fails.

§Panics

Panics when the hook writes or reports more final output units than BufferedEncodeEngine::max_finish_output_len declared.

Trait Implementations§

Source§

impl<C: Clone, H: Clone> Clone for BufferedEncodeEngine<C, H>

Source§

fn clone(&self) -> BufferedEncodeEngine<C, H>

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<C: Copy, H: Copy> Copy for BufferedEncodeEngine<C, H>

Source§

impl<C: Debug, H: Debug> Debug for BufferedEncodeEngine<C, H>

Source§

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

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

impl<C: Default, H: Default> Default for BufferedEncodeEngine<C, H>

Source§

fn default() -> BufferedEncodeEngine<C, H>

Returns the “default value” for a type. Read more
Source§

impl<C: Eq, H: Eq> Eq for BufferedEncodeEngine<C, H>

Source§

impl<C: Hash, H: Hash> Hash for BufferedEncodeEngine<C, H>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<C: PartialEq, H: PartialEq> PartialEq for BufferedEncodeEngine<C, H>

Source§

fn eq(&self, other: &BufferedEncodeEngine<C, H>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<C, H> StructuralPartialEq for BufferedEncodeEngine<C, H>

Auto Trait Implementations§

§

impl<C, H> Freeze for BufferedEncodeEngine<C, H>
where C: Freeze, H: Freeze,

§

impl<C, H> RefUnwindSafe for BufferedEncodeEngine<C, H>

§

impl<C, H> Send for BufferedEncodeEngine<C, H>
where C: Send, H: Send,

§

impl<C, H> Sync for BufferedEncodeEngine<C, H>
where C: Sync, H: Sync,

§

impl<C, H> Unpin for BufferedEncodeEngine<C, H>
where C: Unpin, H: Unpin,

§

impl<C, H> UnsafeUnpin for BufferedEncodeEngine<C, H>
where C: UnsafeUnpin, H: UnsafeUnpin,

§

impl<C, H> UnwindSafe for BufferedEncodeEngine<C, H>
where C: UnwindSafe, H: UnwindSafe,

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 = Infallible

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.