qubit_codec/transcode/adapter/codec_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//! Buffered decoder adapter backed by a low-level codec.
9
10use super::CodecTranscodeDecodeHooks;
11use crate::{
12 CapacityError,
13 Codec,
14 CodecDecodeError,
15 TranscodeDecodeEngine,
16 TranscodeDecoder,
17 TranscodeError,
18 TranscodeProgress,
19 Transcoder,
20};
21
22/// Decodes encoded units into caller-provided value buffers by using a
23/// [`Codec`].
24///
25/// `CodecTranscodeDecoder` is a policy-free bridge from the low-level unchecked
26/// [`Codec`] contract to [`Transcoder`] and [`TranscodeDecoder`]. It
27/// leaves incomplete input tails in the caller-provided input slice; callers
28/// own input-buffer refill and EOF incomplete-tail policy.
29///
30/// # Type Parameters
31///
32/// - `C`: Low-level codec used to decode values.
33#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
34pub struct CodecTranscodeDecoder<C> {
35 /// Common buffered decoding engine.
36 engine: TranscodeDecodeEngine<C, CodecTranscodeDecodeHooks>,
37}
38
39impl<C> CodecTranscodeDecoder<C>
40where
41 C: Codec,
42{
43 /// Creates a buffered decoder backed by `codec`.
44 ///
45 /// # Parameters
46 ///
47 /// - `codec`: Low-level codec used to decode values.
48 ///
49 /// # Returns
50 ///
51 /// Returns a buffered decoder adapter for the supplied codec.
52 #[must_use]
53 #[inline]
54 pub fn new(codec: C) -> Self {
55 Self {
56 engine: TranscodeDecodeEngine::new(
57 codec,
58 CodecTranscodeDecodeHooks,
59 ),
60 }
61 }
62}
63
64impl<C> Transcoder<C::Unit, C::Value> for CodecTranscodeDecoder<C>
65where
66 C: Codec,
67{
68 type Error = CodecDecodeError<C::DecodeError>;
69
70 /// Returns an upper bound for decoded values produced from `input_len`
71 /// units.
72 ///
73 /// # Parameters
74 ///
75 /// - `input_len`: Source units the caller plans to decode.
76 ///
77 /// # Returns
78 ///
79 /// Returns a conservative upper bound for decoded values.
80 #[inline(always)]
81 fn max_output_len(&self, input_len: usize) -> Result<usize, CapacityError> {
82 self.engine.max_output_len(input_len)
83 }
84
85 /// Returns the maximum values emitted by finishing internal state.
86 ///
87 /// # Returns
88 ///
89 /// Returns the number of values that may still be emitted by finishing
90 /// state.
91 #[inline(always)]
92 fn max_finish_output_len(&self) -> Result<usize, CapacityError> {
93 self.engine.max_finish_output_len()
94 }
95
96 /// Returns the maximum values emitted when resetting internal state.
97 #[inline(always)]
98 fn max_reset_output_len(&self) -> Result<usize, CapacityError> {
99 Ok(self.engine.max_reset_output_len())
100 }
101
102 /// Resets codec decode state and hook-owned state.
103 #[inline(always)]
104 fn reset(
105 &mut self,
106 output: &mut [C::Value],
107 output_index: usize,
108 ) -> Result<usize, TranscodeError<Self::Error>> {
109 self.engine.reset(output, output_index)
110 }
111
112 /// Decodes source units into logical values.
113 ///
114 /// # Parameters
115 ///
116 /// - `input`: Source unit slice.
117 /// - `input_index`: Absolute source index where decoding starts.
118 /// - `output`: Destination value slice.
119 /// - `output_index`: Absolute output value index where writing starts.
120 ///
121 /// # Returns
122 ///
123 /// Returns conversion progress for consumed and written counters.
124 ///
125 /// # Errors
126 ///
127 /// Returns a decode error when indices are invalid or when conversion fails
128 /// under hook policy.
129 #[inline(always)]
130 fn transcode(
131 &mut self,
132 input: &[C::Unit],
133 input_index: usize,
134 output: &mut [C::Value],
135 output_index: usize,
136 ) -> Result<TranscodeProgress, TranscodeError<Self::Error>> {
137 self.engine
138 .transcode(input, input_index, output, output_index)
139 }
140
141 /// Finishes internally retained output after EOF.
142 ///
143 /// # Parameters
144 ///
145 /// - `output`: Destination value slice for final retained values.
146 /// - `output_index`: Absolute output value index where writing starts.
147 ///
148 /// # Returns
149 ///
150 /// Returns the number of values written by finalization.
151 ///
152 /// # Errors
153 ///
154 /// Returns a finish error if finalization cannot complete.
155 #[inline(always)]
156 fn finish(
157 &mut self,
158 output: &mut [C::Value],
159 output_index: usize,
160 ) -> Result<usize, TranscodeError<Self::Error>> {
161 self.engine.finish(output, output_index)
162 }
163}
164
165impl<C> TranscodeDecoder<C::Unit, C::Value> for CodecTranscodeDecoder<C> where
166 C: Codec
167{
168}