pub trait TranscodeEncodeHooks<C>where
C: Codec,{
type Error;
type PlanAction;
// Required methods
fn prepare_encode(
&mut self,
codec: &mut C,
input_value: &C::Value,
input_index: usize,
) -> Result<EncodePlan<Self::PlanAction>, Self::Error>;
unsafe fn write_encode(
&mut self,
codec: &mut C,
context: EncodeContext<'_, C::Value, C::Unit>,
plan: EncodePlan<Self::PlanAction>,
) -> Result<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 map_encode_reset_error(
&mut self,
_codec: &mut C,
_error: C::EncodeError,
) -> Self::Error { ... }
unsafe fn write_encode_reset(
&mut self,
codec: &mut C,
output: &mut [C::Unit],
output_index: usize,
) -> Result<usize, Self::Error> { ... }
fn finish(
&mut self,
_codec: &mut C,
_output: &mut [C::Unit],
_output_index: usize,
) -> Result<usize, Self::Error> { ... }
fn reset(&mut self, _codec: &mut C) { ... }
}Expand description
Policy hooks for crate::TranscodeEncodeEngine.
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::{
TranscodeEncodeHooks,
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(
&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<C> TranscodeEncodeHooks<C> for StrictHooks
where
C: Codec,
{
type Error = CodecEncodeError<C::EncodeError>;
type PlanAction = ();
fn prepare_encode(
&mut self,
codec: &mut 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: &mut C,
context: EncodeContext<'_, C::Value, C::Unit>,
_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))
}
}§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: &mut C,
input_value: &C::Value,
input_index: usize,
) -> Result<EncodePlan<Self::PlanAction>, Self::Error>
fn prepare_encode( &mut self, codec: &mut 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: &mut C,
context: EncodeContext<'_, C::Value, C::Unit>,
plan: EncodePlan<Self::PlanAction>,
) -> Result<usize, Self::Error>
unsafe fn write_encode( &mut self, codec: &mut 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.
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 map_encode_reset_error(
&mut self,
_codec: &mut C,
_error: C::EncodeError,
) -> Self::Error
fn map_encode_reset_error( &mut self, _codec: &mut C, _error: C::EncodeError, ) -> Self::Error
Maps a codec-level reset error into this hook’s public error type.
§Parameters
codec: Low-level codec owned by the engine.error: Error returned byCodec::encode_reset.
§Returns
Returns the hook-specific error.
§Required Overrides
The default implementation panics. Override this method whenever
Codec::encode_reset can return an error for C. Leaving the default
is appropriate only when reset is infallible or unreachable for the
codec and hook pairing.
Sourceunsafe fn write_encode_reset(
&mut self,
codec: &mut C,
output: &mut [C::Unit],
output_index: usize,
) -> Result<usize, Self::Error>
unsafe fn write_encode_reset( &mut self, codec: &mut C, output: &mut [C::Unit], output_index: usize, ) -> Result<usize, Self::Error>
Writes encoder reset output through the wrapped codec.
The default implementation delegates to Codec::encode_reset and
maps errors through
map_encode_reset_error.
§Parameters
codec: Low-level codec owned by the engine.output: Destination unit buffer.output_index: Absolute output index where reset output starts.
§Returns
Returns the number of reset units written.
§Errors
Returns hook-specific reset errors.
§Safety
The caller must guarantee that at least
Codec::max_encode_reset_units units are writable from
output_index.
Sourcefn finish(
&mut self,
_codec: &mut C,
_output: &mut [C::Unit],
_output_index: usize,
) -> Result<usize, Self::Error>
fn finish( &mut self, _codec: &mut 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
TranscodeEncodeHooks::max_finish_output_len writable units from
output_index. 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 TranscodeEncodeHooks::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".