Skip to main content

TranscodeEncodeHooks

Trait TranscodeEncodeHooks 

Source
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§

Source

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 that Codec::can_encode_value rejected.
§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§

Source

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.

Source

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.

Source

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.
Source

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".

Implementors§