Skip to main content

qubit_codec/transcode/
transcode_converter.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 converters.
9
10use super::TranscodeConvertError;
11use super::Transcoder;
12
13/// Converts encoded units of one representation into encoded units of another.
14///
15/// `TranscodeConverter` refines [`Transcoder`] for implementations whose
16/// input and output are both encoded unit streams. Any intermediate logical
17/// values are implementation details of the concrete converter.
18///
19/// The trait adds no methods. It exists to make generic bounds distinguish
20/// unit-to-unit conversion from value-to-unit encoding and unit-to-value
21/// decoding.
22///
23/// # Examples
24///
25/// ```
26/// use core::convert::Infallible;
27/// use core::num::NonZeroUsize;
28///
29/// use qubit_codec::CapacityError;
30/// use qubit_codec::TranscodeConvertError;
31/// use qubit_codec::TranscodeConverter;
32/// use qubit_codec::TranscodeProgress;
33/// use qubit_codec::Transcoder;
34///
35/// #[derive(Default)]
36/// struct ByteToWord;
37/// # impl Transcoder for ByteToWord {
38/// #     type Input = u8;
39/// #     type Output = u16;
40/// #     type Error = TranscodeConvertError<Infallible, Infallible, u8>;
41/// #     fn max_transcode_output_len(&self, input_len: usize) -> Result<usize, CapacityError> { Ok(input_len) }
42/// #     fn reset(&mut self, _output: &mut [u16], _index: usize) -> Result<usize, Self::Error> { Ok(0) }
43/// #     fn finish(&mut self, _output: &mut [u16], _index: usize) -> Result<usize, Self::Error> { Ok(0) }
44/// #     fn transcode(&mut self, input: &[u8], input_index: usize, output: &mut [u16], output_index: usize) -> Result<TranscodeProgress, Self::Error> {
45/// #         let source = &input[input_index..];
46/// #         let target = &mut output[output_index..];
47/// #         let count = source.len().min(target.len());
48/// #         for (input, output) in source.iter().zip(target.iter_mut()) { *output = u16::from(*input); }
49/// #         if count == source.len() { Ok(TranscodeProgress::complete(count, count)) }
50/// #         else { Ok(TranscodeProgress::need_output(NonZeroUsize::MIN, count, count)) }
51/// #     }
52/// # }
53/// impl TranscodeConverter for ByteToWord {
54///     type DecodeError = Infallible;
55///     type EncodeError = Infallible;
56///     type Value = u8;
57/// }
58///
59/// let mut converter = ByteToWord::default();
60/// let mut output = [0_u16; 2];
61/// assert_eq!(converter.reset(&mut output, 0).unwrap(), 0);
62/// let progress = converter.transcode(&[7, 9], 0, &mut output, 0).unwrap();
63/// assert_eq!(output, [7, 9]);
64/// assert_eq!(progress, TranscodeProgress::complete(2, 2));
65/// assert_eq!(converter.finish(&mut output, progress.written()).unwrap(), 0);
66/// ```
67pub trait TranscodeConverter:
68    Transcoder<Error = TranscodeConvertError<Self::DecodeError, Self::EncodeError, Self::Value>>
69{
70    /// Domain error type produced by source decoding.
71    type DecodeError;
72
73    /// Domain error type produced by target encoding.
74    type EncodeError;
75
76    /// Intermediate logical value type converted between source and target.
77    type Value;
78}