Skip to main content

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 {}