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