pub trait TranscodeEncodeHooks<C>where
C: Codec,{
// Required method
fn handle_unencodable_encode(
&mut self,
codec: &mut C,
context: &EncodeContext<'_, C::Value>,
) -> Result<EncodeUnencodableAction<C::Value>, TranscodeEncodeErrorOf<C>>;
// Provided methods
fn max_transcode_output_len(
&self,
_codec: &C,
input_len: usize,
) -> Result<usize, CapacityError> { ... }
fn max_finish_output_len(&self, _codec: &C) -> usize { ... }
fn reset_hooks(&mut self, _codec: &mut C) { ... }
fn finish_hooks(
&mut self,
_codec: &mut C,
_output: &mut [C::Unit],
_output_index: usize,
) -> Result<usize, TranscodeEncodeErrorOf<C>> { ... }
}Expand description
Policy hooks for crate::engine::TranscodeEncodeEngine.
Hooks own policy state, such as replacement or ignore behavior, but not the codec or engine cursor state. The engine owns the normal one-value encode operation and calls hooks only when policy decisions are needed.
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, skipping
unsupported values, replacing them with encodable values, resetting
hook-owned state in reset_hooks, or emitting final
state in finish_hooks.
The engine calls
handle_unencodable_encode only after
Codec::can_encode_value returns false for the current input
value. Encodable values are encoded directly by the engine with
Codec::encode_len and Codec::encode.
§Examples
This hook reports unsupported values as adapter-level errors.
use core::convert::Infallible;
use core::num::NonZeroUsize;
use qubit_codec::Codec;
use qubit_codec::DecodeFailure;
use qubit_codec::TranscodeEncodeErrorOf;
use qubit_codec::engine::EncodeContext;
use qubit_codec::engine::EncodeUnencodableAction;
use qubit_codec::engine::TranscodeEncodeEngine;
use qubit_codec::engine::TranscodeEncodeHooks;
#[derive(Clone, Copy)]
struct ByteCodec;
impl Codec for ByteCodec {
type Value = u8;
type Unit = u8;
type DecodeError = Infallible;
type EncodeError = 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>> {
Ok((input[index], NonZeroUsize::MIN))
}
unsafe fn encode(
&mut self,
value: &u8,
output: &mut [u8],
index: usize,
) -> Result<usize, Self::EncodeError> {
output[index] = *value;
Ok(1)
}
}
struct StrictHooks;
impl<C> TranscodeEncodeHooks<C> for StrictHooks
where
C: Codec,
{
fn handle_unencodable_encode(
&mut self,
_codec: &mut C,
_context: &EncodeContext<'_, C::Value>,
) -> Result<EncodeUnencodableAction<C::Value>, TranscodeEncodeErrorOf<C>> {
Ok(EncodeUnencodableAction::Reject)
}
}
let codec = ByteCodec;
let hooks = StrictHooks;
let bound = hooks.max_transcode_output_len(&codec, 1).unwrap();
assert!(bound >= ByteCodec::MAX_ENCODE_UNITS_PER_VALUE);
let mut engine = TranscodeEncodeEngine::new(codec, hooks);
engine.reset(&mut [], 0).unwrap();
let mut output = [0_u8; 1];
let progress = engine.transcode(&[42], 0, &mut output, 0).unwrap();
assert_eq!(progress.read(), 1);
assert_eq!(progress.written(), 1);
assert_eq!(output, [42]);§Type Parameters
C: Low-level codec owned by the engine.
Required Methods§
Sourcefn handle_unencodable_encode(
&mut self,
codec: &mut C,
context: &EncodeContext<'_, C::Value>,
) -> Result<EncodeUnencodableAction<C::Value>, TranscodeEncodeErrorOf<C>>
fn handle_unencodable_encode( &mut self, codec: &mut C, context: &EncodeContext<'_, C::Value>, ) -> Result<EncodeUnencodableAction<C::Value>, TranscodeEncodeErrorOf<C>>
Handles one unencodable input value.
§Parameters
codec: Low-level codec owned by the engine.context: Encode context for the input value thatCodec::can_encode_valuerejected.
§Returns
Returns the action selected by this hook policy.
Replacement actions must contain a value that the same codec can encode. The engine treats unencodable replacements as hook contract violations and panics.
Before invoking this method, the engine requires writable capacity for
Codec::MAX_ENCODE_UNITS_PER_VALUE. This conservative bound also
applies when the selected action is Skip or Reject; it may exceed
the replacement’s actual encoded width. A capacity shortage does not
invoke the hook, so hook state is not changed by output backpressure.
§Errors
Returns crate::TranscodeEncodeError when the policy rejects the
value with a codec-domain error.
Provided Methods§
Sourcefn max_transcode_output_len(
&self,
_codec: &C,
input_len: usize,
) -> Result<usize, CapacityError>
fn max_transcode_output_len( &self, _codec: &C, input_len: usize, ) -> Result<usize, CapacityError>
Returns the maximum output units needed for input_len values.
This bound covers the streaming encode phase, including conservative
capacity preflight in streaming and EOF operations, as required by
crate::Transcoder::max_transcode_output_len. It describes required
writable capacity, not only units actually emitted. It must not include
codec reset output, codec finish output, or hook finish output.
It may depend on immutable hook and codec configuration, but it must
cover every reachable transient hook and codec state. Each streaming
action handles one current input value by skipping it or encoding at
most one replacement; the hook API has no separate operation for
draining hook-owned output without input. Use a custom
crate::Transcoder for streaming behavior beyond this action model,
such as one-to-many output or draining output without new input.
Before handle_unencodable_encode,
the engine may preflight Codec::MAX_ENCODE_UNITS_PER_VALUE, even
when the selected action is Skip or Reject and emits no units.
Thus the bound must leave room for that preflight; zero actual output
does not imply zero required writable capacity. See the
trait example for a capacity check before constructing the
engine.
The default implementation multiplies input_len by
Codec::MAX_ENCODE_UNITS_PER_VALUE. This bound is valid for direct
encoding, skipped unencodable values, and single-value replacements.
Override it when the codec’s streaming output bound requires a larger
value.
§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 for streaming output.
§Errors
Returns CapacityError::OutputLengthOverflow when the bound cannot
be represented as usize.
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 report
the maximum output that could be derived from hook-owned state in any
reachable transient stream state, not only what happens to remain when
this method is called.
The default implementation returns 0. Override it when
finish_hooks can write trailers, checksums,
delayed replacements, or any other hook-owned final output. Do not
include Codec::MAX_ENCODE_FINISH_UNITS; the engine adds the codec
finish bound separately.
§Parameters
codec: Low-level codec owned by the engine.
§Returns
Returns the finite, transient-state-independent final-output upper bound.
Sourcefn reset_hooks(&mut self, _codec: &mut C)
fn reset_hooks(&mut self, _codec: &mut C)
Runs hook-owned cleanup as part of stream reset.
Called before Codec::encode_reset writes
its own reset output. Stateless hooks may use the default no-op.
§Parameters
codec: Low-level codec owned by the engine.
Sourcefn finish_hooks(
&mut self,
_codec: &mut C,
_output: &mut [C::Unit],
_output_index: usize,
) -> Result<usize, TranscodeEncodeErrorOf<C>>
fn finish_hooks( &mut self, _codec: &mut C, _output: &mut [C::Unit], _output_index: usize, ) -> Result<usize, TranscodeEncodeErrorOf<C>>
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.
Called after Codec::encode_finish has
written its own finish output.
§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 a transcode encode 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".