pub struct TranscodeDecodeEngine<C, H> { /* private fields */ }Expand description
Reusable buffered decoding engine for codec-backed decoders.
The engine owns the low-level codec and hook object. It keeps the common
buffered decoding loop private: input-index validation, output-capacity
checks, calls to Codec::decode, hook dispatch, and
crate::TranscodeStatus reporting. Incomplete input tails are left in the
caller-provided input slice; callers own input-buffer refill.
Use this type to build a streaming decoder over a one-value Codec. The
engine decodes into a caller-provided output slice and returns
TranscodeProgress instead of allocating. On success it writes decoded
values directly to output. On codec errors it delegates to
crate::engine::TranscodeDecodeHooks, allowing a policy to skip invalid
units, emit a replacement value, or fail.
The engine stops before reading an incomplete value when fewer than
Codec::MIN_UNITS_PER_VALUE units are available. For variable-width
codecs, the codec may still return an incomplete decode error after that
minimum is satisfied. Both conditions return
crate::TranscodeStatus::NeedInput while the stream is open; at EOF the
hook selects whether to reject, skip, or replace the remaining tail.
For strict decoding that wraps codec errors, use
crate::CodecTranscodeDecoder. Use TranscodeDecodeEngine directly when
invalid input should be repaired, skipped, counted, or otherwise handled by
policy.
§Examples
use core::num::NonZeroUsize;
use qubit_codec::{
Codec,
TranscodeDecodeErrorOf,
DecodeFailure,
TranscodeStatus,
};
use qubit_codec::engine::{
DecodeContext,
DecodeInvalidAction,
TranscodeDecodeEngine,
TranscodeDecodeHooks,
};
#[derive(Clone, Copy)]
struct ByteCodec;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum ByteDecodeError {
Malformed { consumed: NonZeroUsize },
}
impl Codec for ByteCodec {
type Value = u8;
type Unit = u8;
type DecodeError = ByteDecodeError;
type EncodeError = core::convert::Infallible;
const MIN_UNITS_PER_VALUE: usize = 1;
const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
unsafe fn decode(
&mut self,
input: &[u8],
index: usize,
) -> Result<(u8, NonZeroUsize), DecodeFailure<Self::DecodeError>> {
match input[index] {
0xff => Err(DecodeFailure::invalid(
ByteDecodeError::Malformed {
consumed: NonZeroUsize::MIN,
},
NonZeroUsize::MIN,
)),
value => Ok((value, NonZeroUsize::MIN)),
}
}
unsafe fn encode(
&mut self,
value: &u8,
output: &mut [u8],
index: usize,
) -> Result<usize, Self::EncodeError> {
output[index] = *value;
Ok(1)
}
}
struct ReplacementHooks;
impl TranscodeDecodeHooks<ByteCodec> for ReplacementHooks {
fn handle_invalid_decode(
&mut self,
_codec: &mut ByteCodec,
error: &ByteDecodeError,
consumed: Option<NonZeroUsize>,
_context: DecodeContext,
) -> Result<DecodeInvalidAction<u8>, TranscodeDecodeErrorOf<ByteCodec>> {
match error {
ByteDecodeError::Malformed { .. } => {
Ok(DecodeInvalidAction::Emit {
value: b'?',
consumed: consumed.expect("codec reported malformed width"),
})
}
}
}
}
let mut engine = TranscodeDecodeEngine::<_, _>::new(ByteCodec, ReplacementHooks);
let input = [b'a', 0xff, b'b'];
let mut output = [0_u8; 3];
let mut reset_output = [];
engine.reset(&mut reset_output, 0)?;
let progress = engine.transcode(&input, 0, &mut output, 0)?;
match progress.status() {
TranscodeStatus::Complete => assert_eq!(&output[..progress.written()], b"a?b"),
TranscodeStatus::NeedInput { .. } => {
// Keep `input[input_index + progress.read()..]`, append more source
// units, and resume.
}
TranscodeStatus::NeedOutput { .. } => {
// Drain `output[..progress.written()]`, then resume with more output
// room.
}
}§Type Parameters
C: Low-level codec used by the engine.H: Policy hook object used by the engine.
Implementations§
Source§impl<C, H> TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
impl<C, H> TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
Sourcepub fn new(codec: C, hooks: H) -> Self
pub fn new(codec: C, hooks: H) -> Self
Creates a buffered decoder engine.
§Parameters
codec: Low-level codec used for one-value decoding.hooks: Policy hooks used for decode failures.
§Returns
Returns a buffered decoder engine.
§Compile-Time Checks
Fails to compile when the supplied codec declares a zero decode unit
bound or when Codec::MIN_UNITS_PER_VALUE exceeds
Codec::MAX_DECODE_UNITS_PER_VALUE.
Sourcepub const fn codec(&self) -> &C
pub const fn codec(&self) -> &C
Returns the wrapped low-level codec.
§Returns
Returns a shared reference to the codec owned by this engine.
Sourcepub fn codec_mut(&mut self) -> &mut C
pub fn codec_mut(&mut self) -> &mut C
Returns the wrapped low-level codec mutably.
§Returns
Returns a mutable reference to the codec owned by this engine.
Sourcepub const fn hooks(&self) -> &H
pub const fn hooks(&self) -> &H
Returns the decode hooks used by this engine.
§Returns
Returns a shared reference to the hook object owned by this engine.
Sourcepub fn hooks_mut(&mut self) -> &mut H
pub fn hooks_mut(&mut self) -> &mut H
Returns the decode hooks mutably.
§Returns
Returns a mutable reference to the hook object owned by this engine.
Sourcepub fn into_parts(self) -> (C, H)
pub fn into_parts(self) -> (C, H)
Consumes the engine and returns its codec and hooks.
Any lifecycle state owned by the engine is discarded.
§Returns
Returns the wrapped codec followed by the decode hooks.
Sourcepub fn max_transcode_output_len(
&self,
input_len: usize,
) -> Result<usize, CapacityError>
pub fn max_transcode_output_len( &self, input_len: usize, ) -> Result<usize, CapacityError>
Returns an upper bound for decoded values produced from input_len
units.
This bound covers only the streaming decode phase. It is delegated to
TranscodeDecodeHooks::max_transcode_output_len, so it includes hook
policy and is valid for every reachable transient codec and hook state.
Downstream decoders must use this engine-level API for capacity planning
instead of recomputing the bound from Codec constants.
§Parameters
input_len: Number of source units the caller plans to decode.
§Returns
Returns a conservative upper bound, or a capacity error on arithmetic overflow.
§Errors
Returns a capacity error when hook capacity arithmetic overflows.
Sourcepub fn max_finish_output_len(&self) -> Result<usize, CapacityError>
pub fn max_finish_output_len(&self) -> Result<usize, CapacityError>
Returns the global maximum values emitted by finishing codec state and finishing hook-owned state.
§Returns
Returns the sum of Codec::MAX_DECODE_FINISH_VALUES and the
hook-provided final-output bound. The codec finish portion covers values
written by Codec::decode_finish; hook implementations must not
include that portion in
TranscodeDecodeHooks::max_finish_output_len. Both component bounds
cover every reachable transient state.
§Errors
Returns a capacity error when the combined finish bound exceeds
usize::MAX.
Sourcepub fn max_reset_output_len(&self) -> Result<usize, CapacityError>
pub fn max_reset_output_len(&self) -> Result<usize, CapacityError>
Returns the global maximum values emitted when resetting stream state.
§Returns
Returns Ok(Codec::MAX_DECODE_RESET_VALUES) for the wrapped codec.
This query cannot fail.
Stateless decoders always return 0.
Sourcepub fn max_total_output_len(
&self,
input_len: usize,
) -> Result<usize, CapacityError>
pub fn max_total_output_len( &self, input_len: usize, ) -> Result<usize, CapacityError>
Returns the maximum values needed by a complete one-shot decode stream.
The returned bound covers reset output, the streaming decode phase for
input_len units, and finish output. Its components are global across
transient state. Higher-level complete decode helpers should use this
engine-level bound instead of recomputing capacity from Codec
constants, because hook policy may change streaming or finish output.
§Parameters
input_len: Number of source units in the complete stream.
§Returns
Returns the complete-stream output bound, or a capacity error on arithmetic overflow.
§Errors
Returns a capacity error when a component or their sum overflows.
Sourcepub fn reset(
&mut self,
output: &mut [C::Value],
output_index: usize,
) -> Result<usize, TranscodeDecodeErrorOf<C>>
pub fn reset( &mut self, output: &mut [C::Value], output_index: usize, ) -> Result<usize, TranscodeDecodeErrorOf<C>>
Resets codec decode state, runs reset hooks, and emits stream-start values.
The sequence is: validate capacity → run reset_hooks → call
Codec::decode_reset. Stateless decoders (MAX_DECODE_RESET_VALUES == 0) write nothing and return Ok(0).
§Parameters
output: Complete output value slice visible to the decoder.output_index: Absolute output value index where writing starts.
§Returns
Returns the number of reset values written.
§Errors
Returns framework errors when the caller provides invalid or insufficient output capacity. Returns domain errors when codec reset or hook reset handling fails. Capacity and index failures occur before any reset state is changed. Once reset execution starts, an error poisons the engine until a later reset succeeds.
§Panics
Panics if the codec reports more than MAX_DECODE_RESET_VALUES written.
Sourcepub fn transcode(
&mut self,
input: &[C::Unit],
input_index: usize,
output: &mut [C::Value],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
pub fn transcode( &mut self, input: &[C::Unit], input_index: usize, output: &mut [C::Value], output_index: usize, ) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
Decodes source units into caller-provided output values.
§Parameters
input: Complete input unit slice visible to the decoder.input_index: Absolute input unit index where decoding starts.output: Complete output value slice visible to the decoder.output_index: Absolute output value index where writing starts.
§Returns
Returns progress describing input units consumed, output values written, and why decoding stopped.
§Errors
Returns framework errors when either index is outside its slice, and
domain errors when a concrete policy hook rejects a value. Returns
TranscodeFailure::TranscodeBeforeReset when the engine has not
completed its first reset. Returns
TranscodeFailure::TranscodeAfterFinish when the logical stream was
already finished and has not been reset, or
TranscodeFailure::LifecyclePoisoned when an earlier reset or finish
failed after execution started.
§Panics
Panics when codec or hook progress violates declared decode bounds.
Sourcepub fn transcode_eof(
&mut self,
input: &[C::Unit],
input_index: usize,
output: &mut [C::Value],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
pub fn transcode_eof( &mut self, input: &[C::Unit], input_index: usize, output: &mut [C::Value], output_index: usize, ) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
Decodes source units after the caller has established end of input.
This follows the normal streaming contract, except that codec attempts
use Codec::decode_eof. A codec may therefore resolve a trailing
prefix that would remain incomplete in an open stream.
§Parameters
input: Complete source-unit slice.input_index: Absolute index of the next source unit.output: Destination for decoded values.output_index: Absolute index of the next destination slot.
§Returns
Returns consumed/written counts and the reason decoding stopped.
§Errors
Returns framework errors for invalid lifecycle state or slice indices, and policy/domain errors for rejected input, including incomplete EOF tails.
§Panics
Panics when codec or hook progress violates declared decode bounds.
Sourcepub fn finish(
&mut self,
output: &mut [C::Value],
output_index: usize,
) -> Result<usize, TranscodeDecodeErrorOf<C>>
pub fn finish( &mut self, output: &mut [C::Value], output_index: usize, ) -> Result<usize, TranscodeDecodeErrorOf<C>>
Finishes codec and hook-owned output after EOF.
Finalization first finishes decode-side codec state through
Codec::decode_finish, then lets hook implementations finish their
own retained state. The caller must provide enough output capacity for
TranscodeDecodeEngine::max_finish_output_len, which includes both
the codec finish bound and the hook-owned finish bound.
§Parameters
output: Complete output value slice visible to the decoder.output_index: Absolute output value index where writing starts.
§Returns
Returns the number of values written by finalization.
§Errors
Returns framework errors when the caller provides invalid or
insufficient output capacity. Returns domain errors when codec finish or
hook finalization fails. Returns
TranscodeFailure::FinishBeforeReset when the engine has not
completed its first reset. Returns
TranscodeFailure::FinishAfterFinish when the logical stream was
already finished and has not been reset, or
TranscodeFailure::LifecyclePoisoned when an earlier reset or finish
failed after execution started. Capacity and index failures occur before
finish execution and remain retryable; later failures poison the engine
until reset succeeds.
§Panics
Panics when the codec finish writes beyond
Codec::MAX_DECODE_FINISH_VALUES or when the combined codec and hook
finalization writes beyond
TranscodeDecodeEngine::max_finish_output_len.
Sourcepub fn transcode_complete_into(
&mut self,
input: &[C::Unit],
output: &mut [C::Value],
) -> Result<usize, TranscodeDecodeErrorOf<C>>
pub fn transcode_complete_into( &mut self, input: &[C::Unit], output: &mut [C::Value], ) -> Result<usize, TranscodeDecodeErrorOf<C>>
Runs a complete one-shot reset -> transcode -> finish decode stream.
The complete input is supplied as input, and output starts at index
0 in output. Callers that need subranges should slice their
buffers before calling this method. Downstream one-shot decoder
helpers should call this engine method instead of reproducing the
reset, transcode, and finish sequence themselves.
§Parameters
input: Complete source unit slice.output: Output value slice for the whole decoded stream.
§Returns
Returns the number of output values written.
§Errors
Returns framework errors for insufficient output, capacity overflow, or an incomplete EOF tail, and domain errors from reset, decode, or finish.
§Panics
Panics when codec or hook output violates reset, decode, or finish bounds.
Trait Implementations§
Source§impl<C, H> TranscodeDecoder for TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
impl<C, H> TranscodeDecoder for TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
Source§type DecodeError = <C as Codec>::DecodeError
type DecodeError = <C as Codec>::DecodeError
Domain error reported by the wrapped codec while decoding.
Source§impl<C, H> Transcoder for TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
impl<C, H> Transcoder for TranscodeDecodeEngine<C, H>where
C: Codec,
H: TranscodeDecodeHooks<C>,
Source§type Error = TranscodeDecodeError<<C as Codec>::DecodeError>
type Error = TranscodeDecodeError<<C as Codec>::DecodeError>
Framework failures and the wrapped codec’s decode errors.
Source§fn max_transcode_output_len(
&self,
input_len: usize,
) -> Result<usize, CapacityError>
fn max_transcode_output_len( &self, input_len: usize, ) -> Result<usize, CapacityError>
Source§fn max_finish_output_len(&self) -> Result<usize, CapacityError>
fn max_finish_output_len(&self) -> Result<usize, CapacityError>
Source§fn max_reset_output_len(&self) -> Result<usize, CapacityError>
fn max_reset_output_len(&self) -> Result<usize, CapacityError>
Returns an upper bound for values emitted when resetting stream state.
§Returns
Returns the codec reset bound as Ok; this query cannot fail.
Source§fn reset(
&mut self,
output: &mut [C::Value],
output_index: usize,
) -> Result<usize, TranscodeDecodeErrorOf<C>>
fn reset( &mut self, output: &mut [C::Value], output_index: usize, ) -> Result<usize, TranscodeDecodeErrorOf<C>>
Resets hooks and codec state, emitting any stream-start values.
§Parameters
output: Destination value slice.output_index: First writable value index.
§Returns
Returns the number of stream-start values written.
§Errors
Returns invalid-capacity/index errors or codec reset domain errors.
§Panics
Panics if codec reset output exceeds its declared bound.
Source§fn transcode(
&mut self,
input: &[C::Unit],
input_index: usize,
output: &mut [C::Value],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
fn transcode( &mut self, input: &[C::Unit], input_index: usize, output: &mut [C::Value], output_index: usize, ) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
Decodes source units into logical values.
§Parameters
input: Source unit slice.input_index: First source index.output: Destination value slice.output_index: First destination index.
§Returns
Returns consumed/written counts and the stop status.
§Errors
Returns lifecycle/index errors or rejected-input domain errors.
§Panics
Panics if codec or hook progress violates decode bounds.
Source§fn transcode_eof(
&mut self,
input: &[C::Unit],
input_index: usize,
output: &mut [C::Value],
output_index: usize,
) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
fn transcode_eof( &mut self, input: &[C::Unit], input_index: usize, output: &mut [C::Value], output_index: usize, ) -> Result<TranscodeProgress, TranscodeDecodeErrorOf<C>>
Decodes source units after end of input is known.
§Parameters
input: Final source unit slice.input_index: First source index.output: Destination value slice.output_index: First destination index.
§Returns
Returns consumed/written counts and the stop status.
§Errors
Returns lifecycle/index errors or rejected input and incomplete-tail errors.
§Panics
Panics if codec or hook progress violates decode bounds.
Source§fn finish(
&mut self,
output: &mut [C::Value],
output_index: usize,
) -> Result<usize, TranscodeDecodeErrorOf<C>>
fn finish( &mut self, output: &mut [C::Value], output_index: usize, ) -> Result<usize, TranscodeDecodeErrorOf<C>>
Finishes internally retained output after EOF.
§Parameters
output: Destination value slice.output_index: First writable value index.
§Returns
Returns the number of final values written.
§Errors
Returns lifecycle/capacity/index errors or codec/hook finish errors.
§Panics
Panics if finalization output exceeds its declared bounds.
Source§fn max_total_output_len(&self, input_len: usize) -> Result<usize, CapacityError>
fn max_total_output_len(&self, input_len: usize) -> Result<usize, CapacityError>
reset -> transcode -> finish
stream. Read more