pub trait BufferedDecodeHooks<C>where
C: Codec,{
type Error;
// Required methods
fn handle_decode_error(
&mut self,
codec: &C,
error: C::DecodeError,
context: DecodeContext,
) -> Result<DecodeAction<C::Value>, Self::Error>;
fn invalid_input_index(
&mut self,
codec: &C,
index: usize,
input_len: usize,
) -> Self::Error;
fn invalid_output_index(
&mut self,
codec: &C,
index: usize,
output_len: usize,
) -> Self::Error;
// Provided methods
fn max_output_len(
&self,
codec: &C,
input_len: usize,
) -> Result<usize, CapacityError> { ... }
fn max_finish_output_len(&self, _codec: &C) -> usize { ... }
fn finish(
&mut self,
_codec: &C,
_output: &mut [C::Value],
_output_index: usize,
) -> Result<usize, Self::Error> { ... }
fn reset(&mut self, _codec: &C) { ... }
}Expand description
Policy hooks for crate::BufferedDecodeEngine.
Hooks own policy state, such as malformed-input replacement behavior. The engine passes the codec into hook methods when policy code needs codec metadata.
Implement this trait when a buffered decoder needs policy decisions after the low-level codec reports an error. The engine handles input/output cursor bookkeeping, output-capacity checks, and successful one-value decodes; hooks decide whether a decode error means “need more input”, “skip these units”, “emit a replacement value”, or “return an error”.
The hook receives a DecodeContext with absolute input/output cursors, so
errors can include useful positions without duplicating engine arithmetic.
Stateful hooks may also use finish to emit final values
after the caller has supplied all input and handled any incomplete tail.
§Example
This hook maps incomplete codec errors to NeedInput, replaces malformed
units with b'?', and otherwise lets the engine keep decoding.
use core::num::NonZeroUsize;
use qubit_codec::{
BufferedDecodeHooks,
Codec,
CodecDecodeError,
DecodeAction,
DecodeContext,
};
#[derive(Clone, Copy)]
struct MyCodec;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum MyDecodeError {
Incomplete { required_total: usize },
Malformed { consumed: NonZeroUsize },
}
unsafe impl Codec for MyCodec {
type Value = u8;
type Unit = u8;
type DecodeError = MyDecodeError;
type EncodeError = core::convert::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> {
match input[index] {
0xff => Err(MyDecodeError::Malformed {
consumed: NonZeroUsize::MIN,
}),
value => Ok((value, NonZeroUsize::MIN)),
}
}
unsafe fn encode_unchecked(
&self,
value: &u8,
output: &mut [u8],
index: usize,
) -> Result<usize, Self::EncodeError> {
output[index] = *value;
Ok(1)
}
}
struct ReplacementHooks;
impl BufferedDecodeHooks<MyCodec> for ReplacementHooks {
type Error = CodecDecodeError<MyDecodeError>;
fn handle_decode_error(
&mut self,
_codec: &MyCodec,
error: MyDecodeError,
_context: DecodeContext,
) -> Result<DecodeAction<u8>, Self::Error> {
match error {
MyDecodeError::Incomplete { required_total } => {
Ok(DecodeAction::NeedInput { required_total })
}
MyDecodeError::Malformed { consumed } => {
Ok(DecodeAction::Emit { value: b'?', consumed })
}
}
}
fn invalid_input_index(
&mut self,
_codec: &MyCodec,
index: usize,
input_len: usize,
) -> Self::Error {
CodecDecodeError::invalid_input_index(index, input_len)
}
fn invalid_output_index(
&mut self,
_codec: &MyCodec,
index: usize,
output_len: usize,
) -> Self::Error {
CodecDecodeError::invalid_output_index(index, output_len)
}
}§Type Parameters
C: Low-level codec owned by the engine.
Required Associated Types§
Required Methods§
Sourcefn handle_decode_error(
&mut self,
codec: &C,
error: C::DecodeError,
context: DecodeContext,
) -> Result<DecodeAction<C::Value>, Self::Error>
fn handle_decode_error( &mut self, codec: &C, error: C::DecodeError, context: DecodeContext, ) -> Result<DecodeAction<C::Value>, Self::Error>
Handles a codec decode error during transcode.
§Parameters
codec: Low-level codec owned by the engine.error: Error returned by the codec.context: Decode attempt context.
§Returns
Returns the action selected by this hook policy.
Returned actions must be consistent with context.available:
NeedInput.required_totalmust be greater thancontext.available;Skip.consumedandEmit.consumedmust not exceedcontext.available.
The engine treats violations as hook bugs and panics.
§Errors
Returns Self::Error when the policy rejects the input.
Sourcefn invalid_input_index(
&mut self,
codec: &C,
index: usize,
input_len: usize,
) -> Self::Error
fn invalid_input_index( &mut self, codec: &C, index: usize, input_len: usize, ) -> Self::Error
Creates an error for a caller-supplied input index outside the input slice.
The generic engine detects this before invoking the codec. The hook owns the concrete decoder error type, so it also owns the adapter-level error construction.
§Parameters
codec: Low-level codec owned by the engine.index: Invalid input index supplied by the caller.input_len: Length of the input slice.
§Returns
Returns the hook-specific error representing index > input_len.
Sourcefn invalid_output_index(
&mut self,
codec: &C,
index: usize,
output_len: usize,
) -> Self::Error
fn invalid_output_index( &mut self, codec: &C, index: usize, output_len: usize, ) -> Self::Error
Creates an error for a caller-supplied output index outside the output slice.
The generic engine detects this before writing any decoded value. The hook owns the concrete decoder error type, so it also owns the adapter-level error construction.
§Parameters
codec: Low-level codec owned by the engine.index: Invalid output index supplied by the caller.output_len: Length of the output slice.
§Returns
Returns the hook-specific error representing index > output_len.
Provided Methods§
Sourcefn max_output_len(
&self,
codec: &C,
input_len: usize,
) -> Result<usize, CapacityError>
fn max_output_len( &self, codec: &C, input_len: usize, ) -> Result<usize, CapacityError>
Returns an upper bound for decoded values produced from input_len units.
§Parameters
codec: Low-level codec owned by the engine.input_len: Number of source units the caller plans to decode.
§Returns
Returns a conservative upper bound derived from
Codec::min_units_per_value.
Sourcefn max_finish_output_len(&self, _codec: &C) -> usize
fn max_finish_output_len(&self, _codec: &C) -> usize
Returns an upper bound for values emitted by finishing hook-owned state.
finish never receives more input. Implementations must only report
output derived from hook-owned state that remains after the caller has
handled any incomplete input tail.
§Parameters
codec: Low-level codec owned by the engine.
§Returns
Returns the finite final-output upper bound.
Sourcefn finish(
&mut self,
_codec: &C,
_output: &mut [C::Value],
_output_index: usize,
) -> Result<usize, Self::Error>
fn finish( &mut self, _codec: &C, _output: &mut [C::Value], _output_index: usize, ) -> Result<usize, Self::Error>
Finishes hook-owned state and writes any retained output.
The default implementation is a no-op for stateless decode hooks.
Stateful hooks may emit final values such as checksums, reset markers, or
other trailer data. The caller must provide at least
BufferedDecodeHooks::max_finish_output_len writable slots from
output_index. Engines may pass an output slice whose upper bound is
capped at output_index + max_finish_output_len, so implementations must
not write beyond that declared final-output bound.
§Parameters
codec: Low-level codec owned by the engine.output: Output value slice visible to the hook.output_index: Absolute output value index where writing starts.
§Returns
Returns the number of values written by finalization. This count must not
exceed BufferedDecodeHooks::max_finish_output_len.
§Errors
Returns Self::Error when hook-owned state cannot be finalized.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".