pub trait BufferedEncodeHooks<C>where
C: Codec,{
type Error;
type PlanAction;
// Required methods
fn prepare_encode(
&mut self,
codec: &C,
input_value: &C::Value,
input_index: usize,
) -> Result<EncodePlan<Self::PlanAction>, Self::Error>;
unsafe fn write_encode(
&mut self,
codec: &C,
context: EncodeContext<'_, C::Value, C::Unit>,
plan: EncodePlan<Self::PlanAction>,
) -> Result<usize, 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::Unit],
_output_index: usize,
) -> Result<usize, Self::Error> { ... }
fn reset(&mut self, _codec: &C) { ... }
}Expand description
Policy hooks for crate::BufferedEncodeEngine.
Hooks own policy state, such as replacement or ignore behavior, but not the codec or engine cursor state. The engine passes the codec into hook methods when policy code needs codec metadata or one-value encode operations.
Implement this trait when a buffered encoder needs policy decisions around
individual values while reusing the common engine loop. Examples include
rejecting unsupported values with adapter-level context, consuming values
without writing output, writing replacement units, or emitting final state in
finish.
The engine calls prepare_encode before each value
is consumed. The returned EncodePlan states the required output capacity
and may carry an action computed by the hook. Only after that capacity is
available does the engine call write_encode with the
same cursor context and the prepared plan. This split lets the engine stop
with crate::TranscodeStatus::NeedOutput
without consuming the next input value.
§Example
This hook writes each value with the wrapped codec and uses the codec’s maximum width as the capacity plan.
use core::{
convert::Infallible,
num::NonZeroUsize,
};
use qubit_codec::{
BufferedEncodeHooks,
Codec,
CodecEncodeError,
EncodeContext,
EncodePlan,
};
#[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<C> BufferedEncodeHooks<C> for StrictHooks
where
C: Codec,
{
type Error = CodecEncodeError<C::EncodeError>;
type PlanAction = ();
fn prepare_encode(
&mut self,
codec: &C,
_value: &C::Value,
_input_index: usize,
) -> Result<EncodePlan<()>, Self::Error> {
Ok(EncodePlan::new(codec.max_units_per_value().get(), ()))
}
unsafe fn write_encode(
&mut self,
codec: &C,
context: EncodeContext<'_, C::Value, C::Unit>,
_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: &C,
index: usize,
input_len: usize,
) -> Self::Error {
CodecEncodeError::invalid_input_index(index, input_len)
}
fn invalid_output_index(
&mut self,
_codec: &C,
index: usize,
output_len: usize,
) -> Self::Error {
CodecEncodeError::invalid_output_index(index, output_len)
}
}§Type Parameters
C: Low-level codec owned by the engine.
Required Associated Types§
Sourcetype PlanAction
type PlanAction
Concrete action stored in EncodePlan::action.
Required Methods§
Sourcefn prepare_encode(
&mut self,
codec: &C,
input_value: &C::Value,
input_index: usize,
) -> Result<EncodePlan<Self::PlanAction>, Self::Error>
fn prepare_encode( &mut self, codec: &C, input_value: &C::Value, input_index: usize, ) -> Result<EncodePlan<Self::PlanAction>, Self::Error>
Prepares an encoding plan for one input value.
This method must not write output. It decides the output capacity bound
needed before write_encode may be called and
returns an implementation-specific plan action.
§Parameters
codec: Low-level codec owned by the engine.input_value: Input value being encoded.input_index: Absolute input index ofvalue.
§Returns
Returns the write plan for value.
§Errors
Returns Self::Error when this value cannot be encoded under the hook
policy.
Sourceunsafe fn write_encode(
&mut self,
codec: &C,
context: EncodeContext<'_, C::Value, C::Unit>,
plan: EncodePlan<Self::PlanAction>,
) -> Result<usize, Self::Error>
unsafe fn write_encode( &mut self, codec: &C, context: EncodeContext<'_, C::Value, C::Unit>, plan: EncodePlan<Self::PlanAction>, ) -> Result<usize, Self::Error>
Writes one input value according to a previously prepared plan.
This method is called only after the engine has verified that
EncodePlan::max_output_units units from plan are writable from
EncodeContext::output_index. Implementations may rely on that
capacity guarantee and do not need to report output starvation here. If
a value needs more output than the plan declared, fix
prepare_encode to return a larger bound.
§Parameters
codec: Low-level codec owned by the engine.context: Encode-write context containing the input value, input index, output slice, and output cursor.plan: Prepared plan returned byprepare_encode.
§Returns
Returns the number of output units written.
§Errors
Returns Self::Error when writing fails under the hook policy. Output
capacity exhaustion is handled before this method is called and should
not be reported as a write error.
§Safety
The caller must guarantee that at least the corresponding
EncodePlan::max_output_units units are writable from
EncodeContext::output_index in EncodeContext::output.
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
Builds an error for a caller-supplied input index outside the input slice.
The engine calls this hook before it reads input. Keeping this construction in the hook lets codec-backed adapters preserve their own concrete error type without a separate public factory trait.
§Parameters
codec: Low-level codec owned by the engine.index: Invalid absolute input index supplied by the caller.input_len: Length of the input slice.
§Returns
Returns the hook-specific invalid-input-index error.
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
Builds an error for a caller-supplied output index outside the output slice.
The engine calls this hook before it writes output. Keeping this construction in the hook lets codec-backed adapters preserve their own concrete error type without a separate public factory trait.
§Parameters
codec: Low-level codec owned by the engine.index: Invalid absolute output index supplied by the caller.output_len: Length of the output slice.
§Returns
Returns the hook-specific invalid-output-index error.
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 the maximum output units needed for input_len values.
§Parameters
codec: Low-level codec owned by the engine.input_len: Number of input values the caller plans to encode.
§Returns
Returns a conservative upper bound derived from the codec’s
Codec::max_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 units emitted by finishing hook-owned state.
finish never receives more input values. Implementations must only
report output derived from hook-owned state that remains after the caller
has supplied all input.
§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::Unit],
_output_index: usize,
) -> Result<usize, Self::Error>
fn finish( &mut self, _codec: &C, _output: &mut [C::Unit], _output_index: usize, ) -> Result<usize, Self::Error>
Finishes hook-owned state and writes any retained output units.
The default implementation is a no-op for stateless encode hooks.
Stateful hooks may emit final units such as reset sequences, checksums, or
trailers. The caller must provide at least
BufferedEncodeHooks::max_finish_output_len writable units 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 unit slice visible to the hook.output_index: Absolute output unit index where writing starts.
§Returns
Returns the number of units written by finalization. This count must not
exceed BufferedEncodeHooks::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".