pub struct TranscodeEncodeEngine<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::CodecTranscodeEncoder. Use TranscodeEncodeEngine 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::{
TranscodeEncodeEngine,
TranscodeEncodeHooks,
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(
&mut self,
input: &[u8],
index: usize,
) -> Result<(u8, NonZeroUsize), Self::DecodeError> {
Ok((input[index], NonZeroUsize::MIN))
}
unsafe fn encode(
&mut self,
value: &u8,
output: &mut [u8],
index: usize,
) -> Result<NonZeroUsize, Self::EncodeError> {
output[index] = *value;
Ok(NonZeroUsize::MIN)
}
}
struct StrictHooks;
impl TranscodeEncodeHooks<ByteCodec> for StrictHooks {
type Error = CodecEncodeError<Infallible>;
type PlanAction = ();
fn prepare_encode(
&mut self,
codec: &mut 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: &mut ByteCodec,
context: EncodeContext<'_, u8, u8>,
_plan: EncodePlan<()>,
) -> Result<usize, Self::Error> {
unsafe {
codec.encode(context.input_value, context.output, context.output_index)
}
.map(NonZeroUsize::get)
.map_err(|error| CodecEncodeError::encode(error, context.input_index))
}
}
let mut engine = TranscodeEncodeEngine::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> TranscodeEncodeEngine<C, H>where
C: Codec,
H: TranscodeEncodeHooks<C>,
impl<C, H> TranscodeEncodeEngine<C, H>where
C: Codec,
H: TranscodeEncodeHooks<C>,
Sourcepub fn new(codec: C, hooks: H) -> Self
pub 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.
§Panics
Panics when the supplied codec violates the
Codec::min_units_per_value / Codec::max_units_per_value ordering
invariant.
Sourcepub fn max_output_len(&self, input_len: usize) -> Result<usize, CapacityError>
pub fn max_output_len(&self, input_len: usize) -> Result<usize, CapacityError>
Sourcepub fn max_reset_output_len(&self) -> usize
pub fn max_reset_output_len(&self) -> usize
Gets the maximum output units emitted by stream reset.
§Returns
the codec’s reset-output upper bound.
Sourcepub fn max_finish_output_len(&self) -> usize
pub fn max_finish_output_len(&self) -> usize
Gets the maximum output units emitted by finishing hook-owned state.
§Returns
the hook-provided final output bound.
Sourcepub fn reset(
&mut self,
output: &mut [C::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<H::Error>>
pub fn reset( &mut self, output: &mut [C::Unit], output_index: usize, ) -> Result<usize, TranscodeError<H::Error>>
Resets codec encode state, hook-owned state, and stream-start output.
§Parameters
output: Complete output unit slice visible to the encoder.output_index: Absolute output unit index where writing starts.
§Returns
Returns the number of reset units written.
§Errors
Returns hook errors when the caller provides invalid or insufficient output capacity, or when reset output cannot be emitted.
Sourcepub fn transcode(
&mut self,
input: &[C::Value],
input_index: usize,
output: &mut [C::Unit],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeError<H::Error>>
pub fn transcode( &mut self, input: &[C::Value], input_index: usize, output: &mut [C::Unit], output_index: usize, ) -> Result<TranscodeProgress, TranscodeError<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.
Sourcepub fn finish(
&mut self,
output: &mut [C::Unit],
output_index: usize,
) -> Result<usize, TranscodeError<H::Error>>
pub fn finish( &mut self, output: &mut [C::Unit], output_index: usize, ) -> Result<usize, TranscodeError<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 TranscodeEncodeEngine::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 hook errors 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
TranscodeEncodeEngine::max_finish_output_len declared.
Trait Implementations§
Source§impl<C: Clone, H: Clone> Clone for TranscodeEncodeEngine<C, H>
impl<C: Clone, H: Clone> Clone for TranscodeEncodeEngine<C, H>
Source§fn clone(&self) -> TranscodeEncodeEngine<C, H>
fn clone(&self) -> TranscodeEncodeEngine<C, H>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl<C: Copy, H: Copy> Copy for TranscodeEncodeEngine<C, H>
Source§impl<C, H> Default for TranscodeEncodeEngine<C, H>
impl<C, H> Default for TranscodeEncodeEngine<C, H>
impl<C: Eq, H: Eq> Eq for TranscodeEncodeEngine<C, H>
Source§impl<C: PartialEq, H: PartialEq> PartialEq for TranscodeEncodeEngine<C, H>
impl<C: PartialEq, H: PartialEq> PartialEq for TranscodeEncodeEngine<C, H>
Source§fn eq(&self, other: &TranscodeEncodeEngine<C, H>) -> bool
fn eq(&self, other: &TranscodeEncodeEngine<C, H>) -> bool
self and other values to be equal, and is used by ==.