qubit_codec/codec/codec.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//! Low-level value codec trait.
9
10use core::num::NonZeroUsize;
11
12/// Encodes and decodes one value or codec quantum against a unit buffer.
13///
14/// `Codec` is the lowest-level abstraction in the codec stack. It is intended
15/// for hot paths that have already validated buffer capacity and want to avoid
16/// constructing subslices for every value. Higher-level transcoders and
17/// convenience APIs are responsible for checked buffer management and owned
18/// output allocation.
19///
20/// `min_units_per_value` and `max_units_per_value` describe the representation
21/// width bounds for one value. The minimum is a lower-bound hint for checked
22/// layers: if fewer than this many units are available, no complete value can
23/// exist, so a streaming caller can request more input, report an incomplete
24/// EOF tail. For decoding, this minimum is the smallest safety precondition
25/// checked callers must satisfy before entering
26/// [`decode`](Self::decode). The maximum is a value-independent upper bound
27/// callers can use for coarse capacity planning. For encoding a known value,
28/// checked callers should reserve the exact [`encode_len`](Self::encode_len)
29/// instead of pessimistically reserving the maximum width.
30///
31/// A codec may keep decode-side and encode-side stream state. That state is an
32/// implementation detail owned by the codec. Callers do not snapshot or restore
33/// it; implementations must keep their own state internally consistent across
34/// every public operation, including operations that return `Err`.
35///
36/// # Associated Types
37///
38/// - `Value`: Logical value decoded from or encoded into the buffer. This may
39/// be a scalar such as `u8`, `u16`, `u64`, a `char`, or a fixed quantum such
40/// as `[u8; 3]`. The trait can model other small value objects, but it is
41/// intentionally aimed at copyable value-domain types rather than owned
42/// resource handles or heap-backed aggregates. Implementations must provide
43/// [`Copy`] and [`Default`] so checked adapters can pass values by copy and
44/// allocate flush scratch buffers.
45/// - `Unit`: Buffer unit used by the encoded representation. Implementations
46/// are typically scalar storage units such as `u8`, `u16`, or `char`.
47/// Implementations must provide [`Copy`] and [`Default`] so checked adapters
48/// can allocate output unit buffers and initialize caller-owned scratch
49/// storage.
50///
51/// # Safety
52///
53/// Implementors must uphold the safety contract documented by
54/// [`decode`](Self::decode), [`encode`](Self::encode),
55/// [`encode_reset`](Self::encode_reset), and
56/// [`decode_flush`](Self::decode_flush). In particular, unchecked
57/// implementations must not read or write outside the caller-provided ranges.
58/// Implementations should use `debug_assert!` to state the expected buffer
59/// bounds at the unchecked entry point.
60///
61/// Implementations must also guarantee that
62/// [`min_units_per_value`](Self::min_units_per_value) is less than or equal to
63/// [`max_units_per_value`](Self::max_units_per_value). Both bounds are non-zero
64/// by type, and `max_units_per_value` must be a valid upper bound for one
65/// complete encoded value or codec quantum. Checked adapters assert this
66/// invariant before using codec-provided bounds.
67pub unsafe trait Codec {
68 /// The type of logical values decoded from or encoded into the buffer.
69 type Value: Copy + Default;
70
71 /// The type of buffer units used by the encoded representation.
72 type Unit: Copy + Default;
73
74 /// The type of errors reported when decoding malformed units.
75 type DecodeError;
76
77 /// The type of errors reported when encoding an unsupported value.
78 type EncodeError;
79
80 /// Returns the minimum possible unit count for one encoded value.
81 ///
82 /// This is a lower bound used by checked callers for planning and fast
83 /// impossibility checks. If a streaming decoder has fewer than this many
84 /// readable units, no complete value can be present at the current
85 /// position. If the stream has reached EOF, such a tail is necessarily
86 /// incomplete; otherwise the caller should read more input. Similarly,
87 /// an encoder or transcoder can avoid calling into the codec when the
88 /// remaining output capacity is smaller than this lower bound.
89 ///
90 /// This value does not prove that encoding will fit. For variable-width
91 /// representations, a value may require more units, up to
92 /// [`max_units_per_value`](Self::max_units_per_value). For decoding, this
93 /// is the minimum safety precondition required by
94 /// [`decode`](Self::decode); if fewer units are
95 /// available, a checked caller must request more input or report a closed
96 /// incomplete tail without calling into the unchecked method.
97 ///
98 /// # Returns
99 ///
100 /// Returns a non-zero lower bound for one complete value. Variable-width
101 /// codecs such as LEB128 should return the shortest valid representation
102 /// length. For example, a UTF-16 byte codec can return `2`, while its
103 /// maximum is `4` because a surrogate pair needs four bytes.
104 #[must_use]
105 fn min_units_per_value(&self) -> NonZeroUsize;
106
107 /// Returns the maximum non-zero unit count needed to encode or decode one
108 /// value.
109 ///
110 /// # Returns
111 ///
112 /// Returns an upper bound for one complete value or codec quantum.
113 #[must_use]
114 fn max_units_per_value(&self) -> NonZeroUsize;
115
116 /// Returns whether `value` is in this codec's encodable value domain.
117 ///
118 /// The default implementation returns `true`, which is correct for codecs
119 /// whose [`Value`](Self::Value) type contains only values they can encode.
120 /// Codecs whose logical value type is broader than their representation
121 /// domain, such as an ASCII codec with `Value = char`, must override this
122 /// method.
123 ///
124 /// Checked encoder adapters call this method before querying
125 /// [`encode_len`](Self::encode_len) or entering the unsafe
126 /// [`encode`](Self::encode) method. Direct unsafe callers must do the same.
127 ///
128 /// # Parameters
129 ///
130 /// - `value`: Value whose encodability is queried.
131 ///
132 /// # Returns
133 ///
134 /// Returns `true` when `value` may be passed to
135 /// [`encode_len`](Self::encode_len) and [`encode`](Self::encode).
136 #[inline(always)]
137 #[must_use]
138 fn can_encode_value(&self, _value: &Self::Value) -> bool {
139 true
140 }
141
142 /// Returns the exact non-zero unit count this codec will write when
143 /// encoding `value`.
144 ///
145 /// The default implementation returns
146 /// [`max_units_per_value`](Self::max_units_per_value), which is the
147 /// conservative bound callers can use when no specific value is available.
148 /// Fixed-width codecs do not need to override this method.
149 ///
150 /// Variable-width codecs (LEB128, UTF-8, GB18030, …) should override this
151 /// to report the true encoded length for encodable `value`s. Doing so lets
152 /// buffered adapters and stream writers reserve only what is actually
153 /// needed and enables capacity probing without performing the encode.
154 /// Default codec-backed encoders use this exact value for per-value output
155 /// capacity. The contract requires callers to use this method only when
156 /// [`can_encode_value`](Self::can_encode_value) returned `true` for the
157 /// same `value`. Under that precondition, the returned length must equal
158 /// the unit count [`encode`](Self::encode) writes for the same `value`
159 /// under the same codec state, and must never exceed
160 /// [`max_units_per_value`](Self::max_units_per_value).
161 ///
162 /// # Parameters
163 ///
164 /// - `value`: Value whose encoded length is queried.
165 ///
166 /// # Returns
167 ///
168 /// Returns the non-zero unit count [`encode`](Self::encode) will write for
169 /// an encodable `value`.
170 #[inline(always)]
171 #[must_use]
172 fn encode_len(&self, _value: &Self::Value) -> NonZeroUsize {
173 self.max_units_per_value()
174 }
175
176 /// Returns the maximum unit count emitted when resetting encode state.
177 ///
178 /// Stateful encoders may need a stream-start sequence, such as a byte order
179 /// mark, before the first encoded value. Buffered encoders use this bound
180 /// to reserve output capacity before calling
181 /// [`encode_reset`](Self::encode_reset).
182 ///
183 /// # Returns
184 ///
185 /// Returns the finite reset-output upper bound. Stateless codecs should
186 /// use the default `0`.
187 #[inline(always)]
188 #[must_use]
189 fn max_encode_reset_units(&self) -> usize {
190 0
191 }
192
193 /// Returns the maximum value count emitted when flushing decode state.
194 ///
195 /// Stateful decoders may need to produce final values at EOF from retained
196 /// state. Buffered decoders use this bound to reserve output capacity
197 /// before calling [`decode_flush`](Self::decode_flush).
198 ///
199 /// # Returns
200 ///
201 /// Returns the finite flush-output upper bound. Stateless codecs should
202 /// use the default `0`.
203 #[inline(always)]
204 #[must_use]
205 fn max_decode_flush_values(&self) -> usize {
206 0
207 }
208
209 /// Emits stream-start output and resets encode-side state.
210 ///
211 /// # Parameters
212 ///
213 /// - `output`: Destination unit buffer.
214 /// - `index`: Start index in `output`.
215 ///
216 /// # Returns
217 ///
218 /// Returns the number of reset units written.
219 ///
220 /// # Errors
221 ///
222 /// Returns `Self::EncodeError` when reset output cannot be emitted.
223 /// Implementations must leave their internal state consistent when
224 /// returning an error.
225 ///
226 /// # Safety
227 ///
228 /// The caller must guarantee that the implementation can write up to
229 /// [`max_encode_reset_units`](Self::max_encode_reset_units) units starting
230 /// at `index`.
231 #[inline(always)]
232 #[must_use = "reset output and reset errors must be handled"]
233 unsafe fn encode_reset(
234 &mut self,
235 _output: &mut [Self::Unit],
236 _index: usize,
237 ) -> Result<usize, Self::EncodeError> {
238 Ok(0)
239 }
240
241 /// Encodes one borrowed value into `output` starting at `index`.
242 ///
243 /// # Parameters
244 ///
245 /// - `value`: Value to encode.
246 /// - `output`: Destination unit buffer.
247 /// - `index`: Start index in `output`.
248 ///
249 /// # Returns
250 ///
251 /// Returns the non-zero number of written units. A successful encode
252 /// always emits at least one unit; stateful encoders that need to defer
253 /// output should report that intent through a custom encode error
254 /// instead of returning a zero count.
255 ///
256 /// # Errors
257 ///
258 /// Returns `Self::EncodeError` for encode-side state or representation
259 /// failures other than a value being outside the codec's encodable domain.
260 /// Checked callers reject values for which
261 /// [`can_encode_value`](Self::can_encode_value) returns `false` before
262 /// entering this unsafe method. Implementations must leave their internal
263 /// state consistent when returning an error.
264 ///
265 /// # Safety
266 ///
267 /// The caller must guarantee that
268 /// [`can_encode_value`](Self::can_encode_value) returned `true` for
269 /// `value`, and that the implementation can write at least
270 /// [`encode_len`](Self::encode_len) units for the same `value` and codec
271 /// state starting at `index`. On success, implementations must return that
272 /// exact written unit count, and the count must be no larger than
273 /// [`max_units_per_value`](Self::max_units_per_value).
274 #[must_use = "encoded length and encode errors must be handled"]
275 unsafe fn encode(
276 &mut self,
277 value: &Self::Value,
278 output: &mut [Self::Unit],
279 index: usize,
280 ) -> Result<NonZeroUsize, Self::EncodeError>;
281
282 /// Decodes one value from `input` starting at `index`.
283 ///
284 /// # Parameters
285 ///
286 /// - `input`: Source unit buffer.
287 /// - `index`: Start index in `input`.
288 ///
289 /// # Returns
290 ///
291 /// Returns the decoded value and the non-zero number of consumed units.
292 ///
293 /// # Errors
294 ///
295 /// Returns `Self::DecodeError` when the units are malformed, non-canonical,
296 /// incomplete, or otherwise invalid for this codec. The concrete error type
297 /// carries the codec-specific reason and context. Implementations must
298 /// leave their internal state consistent when returning an error.
299 ///
300 /// # Safety
301 ///
302 /// The caller must guarantee that `index` is a valid boundary in `input`
303 /// and that at least [`min_units_per_value`](Self::min_units_per_value)
304 /// units are readable from `index`. Implementations must not read beyond
305 /// the currently available units under that precondition. They may
306 /// return `Self::DecodeError` when those units are a valid but
307 /// incomplete prefix.
308 ///
309 /// On success, implementations must return a consumed unit count no larger
310 /// than the available input. The return type guarantees that successful
311 /// decoding always consumes at least one unit. Implementations should use
312 /// `debug_assert!` to state these unchecked entry-point assumptions.
313 #[must_use = "decoded value, consumed length, and decode errors must be handled"]
314 unsafe fn decode(
315 &mut self,
316 input: &[Self::Unit],
317 index: usize,
318 ) -> Result<(Self::Value, NonZeroUsize), Self::DecodeError>;
319
320 /// Flushes decode-side EOF state into `output`.
321 ///
322 /// # Parameters
323 ///
324 /// - `output`: Destination value buffer.
325 /// - `index`: Start index in `output`.
326 ///
327 /// # Returns
328 ///
329 /// Returns the number of flushed values written.
330 ///
331 /// # Errors
332 ///
333 /// Returns `Self::DecodeError` when retained decode state is invalid at
334 /// EOF. Implementations must leave their internal state consistent when
335 /// returning an error.
336 ///
337 /// # Safety
338 ///
339 /// The caller must guarantee that the implementation can write up to
340 /// [`max_decode_flush_values`](Self::max_decode_flush_values) values
341 /// starting at `index`.
342 #[inline(always)]
343 #[must_use = "flush output length and flush errors must be handled"]
344 unsafe fn decode_flush(
345 &mut self,
346 _output: &mut [Self::Value],
347 _index: usize,
348 ) -> Result<usize, Self::DecodeError> {
349 Ok(0)
350 }
351}
352
353/// Asserts the public unit-bound invariant required by [`Codec`].
354///
355/// # Type Parameters
356///
357/// - `C`: Codec implementation to validate.
358///
359/// # Returns
360///
361/// Returns unit `()`.
362///
363/// # Panics
364///
365/// Panics when [`Codec::min_units_per_value`] is greater than
366/// [`Codec::max_units_per_value`].
367pub(crate) fn assert_unit_bounds<C>(codec: &C)
368where
369 C: Codec,
370{
371 assert!(
372 codec.min_units_per_value() <= codec.max_units_per_value(),
373 "Codec::min_units_per_value() must not exceed Codec::max_units_per_value()",
374 );
375}