qubit_codec/buffered/codec_buffered_encoder.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 encoder adapter backed by a low-level codec.
11
12use super::{
13 BufferedEncoder,
14 BufferedTranscoder,
15 FinishError,
16 TranscodeProgress,
17 buffered_encode_engine::BufferedEncodeEngine,
18 codec_buffered_encode_hooks::CodecBufferedEncodeHooks,
19};
20use crate::{
21 CapacityError,
22 Codec,
23 CodecEncodeError,
24};
25
26/// Encodes values into caller-provided output units by using a [`Codec`].
27///
28/// `CodecBufferedEncoder` is the default bridge from the low-level unchecked
29/// [`Codec`] contract to the buffered [`BufferedTranscoder`] and [`BufferedEncoder`]
30/// contracts. It encodes complete values only; when the remaining output
31/// capacity is smaller than `codec.max_units_per_value()`, it stops before
32/// consuming the next input value and reports [`crate::TranscodeStatus::NeedOutput`].
33///
34/// # Type Parameters
35///
36/// - `C`: Low-level codec used to encode values.
37#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
38pub struct CodecBufferedEncoder<C> {
39 /// Common buffered encoding engine.
40 engine: BufferedEncodeEngine<C, CodecBufferedEncodeHooks>,
41}
42
43impl<C> CodecBufferedEncoder<C>
44where
45 C: Codec,
46{
47 /// Creates a buffered encoder backed by `codec`.
48 ///
49 /// # Parameters
50 ///
51 /// - `codec`: Low-level codec used to encode values.
52 ///
53 /// # Returns
54 ///
55 /// Returns a buffered encoder adapter for the supplied codec.
56 #[must_use]
57 #[inline(always)]
58 pub const fn new(codec: C) -> Self {
59 Self {
60 engine: BufferedEncodeEngine::new(codec, CodecBufferedEncodeHooks),
61 }
62 }
63}
64
65impl<C> BufferedTranscoder<C::Value, C::Unit> for CodecBufferedEncoder<C>
66where
67 C: Codec,
68{
69 type Error = CodecEncodeError<C::EncodeError>;
70
71 /// Returns the maximum number of output units needed for `input_len` values.
72 ///
73 /// # Parameters
74 ///
75 /// - `input_len`: Logical input values the caller plans to encode.
76 ///
77 /// # Returns
78 ///
79 /// Returns a conservative upper bound for output units.
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 units emitted by finishing internal state.
86 ///
87 /// # Returns
88 ///
89 /// Returns the number of units that may be emitted by finishing state.
90 #[inline(always)]
91 fn max_finish_output_len(&self) -> Result<usize, CapacityError> {
92 Ok(self.engine.max_finish_output_len())
93 }
94
95 /// Resets hook-owned state.
96 ///
97 /// # Returns
98 ///
99 /// Returns unit `()`.
100 #[inline(always)]
101 fn reset(&mut self) {
102 self.engine.reset();
103 }
104
105 /// Encodes values into the supplied output buffer.
106 ///
107 /// # Parameters
108 ///
109 /// - `input`: Input value slice.
110 /// - `input_index`: Absolute input index where encoding starts.
111 /// - `output`: Destination unit slice.
112 /// - `output_index`: Absolute output index where writing starts.
113 ///
114 /// # Returns
115 ///
116 /// Returns conversion progress for consumed input and produced output units.
117 ///
118 /// # Errors
119 ///
120 /// Returns an encode error when indices are invalid or when encoding cannot
121 /// continue under current policy.
122 #[inline(always)]
123 fn transcode(
124 &mut self,
125 input: &[C::Value],
126 input_index: usize,
127 output: &mut [C::Unit],
128 output_index: usize,
129 ) -> Result<TranscodeProgress, Self::Error> {
130 self.engine.transcode(input, input_index, output, output_index)
131 }
132
133 /// Finishes internally retained output after EOF.
134 ///
135 /// # Parameters
136 ///
137 /// - `output`: Destination unit slice for finalization output.
138 /// - `output_index`: Absolute output index where writing starts.
139 ///
140 /// # Returns
141 ///
142 /// Returns the number of units written by finalization.
143 ///
144 /// # Errors
145 ///
146 /// Returns a finish error if retained output cannot be fully emitted.
147 #[inline(always)]
148 fn finish(&mut self, output: &mut [C::Unit], output_index: usize) -> Result<usize, FinishError<Self::Error>> {
149 self.engine.finish(output, output_index)
150 }
151}
152
153impl<C> BufferedEncoder<C::Value, C::Unit> for CodecBufferedEncoder<C> where C: Codec {}