Skip to main content

qubit_codec/transcode/
transcode_decoder.rs

1// =============================================================================
2//    Copyright (c) 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Semantic marker trait for buffered decoders.
9
10use super::TranscodeDecodeError;
11use super::Transcoder;
12
13/// Decodes encoded units into logical values over caller-provided buffers.
14///
15/// `TranscodeDecoder` refines [`Transcoder`] for implementations whose
16/// input is the encoded unit stream and whose output is the logical value
17/// stream. The trait adds no methods; it exists to make generic bounds
18/// distinguish decoding direction from encoding and unit-to-unit conversion.
19///
20/// The word "buffered" describes the caller-managed buffer and progress model.
21/// It does not require the implementor to own an internal buffer.
22///
23/// # Examples
24///
25/// ```
26/// use core::convert::Infallible;
27/// use core::num::NonZeroUsize;
28///
29/// use qubit_codec::Codec;
30/// use qubit_codec::CodecTranscodeDecoder;
31/// use qubit_codec::DecodeFailure;
32/// use qubit_codec::TranscodeDecoder;
33/// use qubit_codec::Transcoder;
34///
35/// # struct IdentityCodec;
36/// # impl Codec for IdentityCodec {
37/// #     type Value = u8;
38/// #     type Unit = u8;
39/// #     type DecodeError = Infallible;
40/// #     type EncodeError = Infallible;
41/// #     const MIN_UNITS_PER_VALUE: usize = 1;
42/// #     const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
43/// #     const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
44/// #     unsafe fn decode(&mut self, input: &[u8], index: usize)
45/// #         -> Result<(u8, NonZeroUsize), DecodeFailure<Infallible>> {
46/// #         Ok((input[index], NonZeroUsize::MIN))
47/// #     }
48/// #     unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
49/// #         -> Result<usize, Infallible> {
50/// #         output[index] = *value;
51/// #         Ok(1)
52/// #     }
53/// # }
54/// fn accepts_decoder<D: TranscodeDecoder>(_: &D) {}
55/// let mut decoder = CodecTranscodeDecoder::new(IdentityCodec);
56/// accepts_decoder(&decoder);
57/// let mut values = [0_u8; 1];
58/// decoder.reset(&mut values, 0).unwrap();
59/// let progress = decoder.transcode(&[7_u8], 0, &mut values, 0).unwrap();
60/// assert_eq!(progress.read(), 1);
61/// assert_eq!(progress.written(), 1);
62/// assert_eq!(values, [7]);
63/// ```
64pub trait TranscodeDecoder: Transcoder<Error = TranscodeDecodeError<Self::DecodeError>> {
65    /// Domain error type produced by decode internals.
66    type DecodeError;
67}