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
12use super::decode_failure::DecodeFailure;
13
14/// Encodes and decodes one value or codec quantum against a unit buffer.
15///
16/// `Codec` is the lowest-level abstraction in the codec stack. It is intended
17/// for hot paths that have already validated buffer capacity and want to avoid
18/// constructing subslices for every value. Higher-level transcoders and
19/// convenience APIs are responsible for checked buffer management and owned
20/// output allocation.
21///
22/// `MIN_UNITS_PER_VALUE` and `MAX_UNITS_PER_VALUE` describe the representation
23/// width bounds for one value. The minimum is a lower-bound hint for checked
24/// layers: if fewer than this many units are available, no complete value can
25/// exist, so a streaming caller can request more input, report an incomplete
26/// EOF tail. For decoding, this minimum is the smallest safety precondition
27/// checked callers must satisfy before entering
28/// [`decode`](Self::decode). The maximum is a value-independent upper bound
29/// callers can use for coarse capacity planning. For encoding a known value,
30/// checked callers should reserve the exact [`encode_len`](Self::encode_len)
31/// instead of pessimistically reserving the maximum width.
32///
33/// A codec may keep decode-side and encode-side stream state. That state is an
34/// implementation detail owned by the codec. Callers do not snapshot or restore
35/// it; implementations must keep their own state internally consistent across
36/// every public operation, including operations that return `Err`.
37///
38/// Decode operations see only the currently supplied input slice and codec
39/// state. They do not receive an explicit EOF marker and they cannot look past
40/// the visible input. Returning [`DecodeFailure::Incomplete`] requests
41/// more input for the current value; it is not itself an EOF error. The default
42/// codec-backed streaming adapters therefore fit formats whose value boundary
43/// is locally decidable from the visible prefix plus codec state. Formats that
44/// require EOF-aware maximal-munch parsing, delayed boundary decisions, or
45/// reinterpretation of an incomplete tail at EOF should put that policy in a
46/// custom [`crate::Transcoder`] or value-level facade instead of relying on the
47/// default `Codec` bridge.
48///
49/// # Associated Types
50///
51/// - `Value`: Logical value decoded from or encoded into the buffer. This may
52/// be a scalar such as `u8`, `u16`, `u64`, a `char`, a fixed quantum such as
53/// `[u8; 3]`, or an owned value such as `String`/`Vec<u8>`. Adapters that
54/// need scratch initialization add their own bounds at the use site.
55/// - `Unit`: Buffer unit used by the encoded representation. Implementations
56/// are typically scalar storage units such as `u8`, `u16`, or `char`.
57/// Adapters that allocate owned output add their own initialization bounds at
58/// the use site.
59///
60/// Implementors must uphold the safety contract documented by
61/// [`decode`](Self::decode), [`encode`](Self::encode),
62/// [`encode_reset`](Self::encode_reset), and
63/// [`decode_flush`](Self::decode_flush). Unchecked implementations must not
64/// read or write outside the caller-provided ranges. Implementations should use
65/// `debug_assert!` to state the expected buffer bounds at the unchecked entry
66/// point.
67///
68/// Implementations must also guarantee that
69/// [`MIN_UNITS_PER_VALUE`](Self::MIN_UNITS_PER_VALUE) is less than or equal to
70/// [`MAX_UNITS_PER_VALUE`](Self::MAX_UNITS_PER_VALUE). Both bounds are non-zero
71/// by type, and `MAX_UNITS_PER_VALUE` must be a valid upper bound for one
72/// complete encoded value or codec quantum. Checked adapters assert this
73/// invariant before using codec-provided bounds.
74pub trait Codec {
75 /// The type of logical values decoded from or encoded into the buffer.
76 type Value;
77
78 /// The type of buffer units used by the encoded representation.
79 type Unit;
80
81 /// The type of errors reported when decoding malformed units.
82 type DecodeError;
83
84 /// The type of errors reported when encoding an unsupported value.
85 type EncodeError;
86
87 /// The minimum possible unit count for one encoded value.
88 ///
89 /// This is a lower bound used by checked callers for planning and fast
90 /// impossibility checks. If a streaming decoder has fewer than this many
91 /// readable units, no complete value can be present at the current
92 /// position.
93 const MIN_UNITS_PER_VALUE: NonZeroUsize = NonZeroUsize::MIN;
94
95 /// The maximum non-zero unit count needed to encode or decode one value.
96 ///
97 /// This is a value-independent upper bound for one complete encoded value
98 /// or codec quantum.
99 const MAX_UNITS_PER_VALUE: NonZeroUsize = NonZeroUsize::MIN;
100
101 /// The maximum unit count emitted when resetting encode state.
102 ///
103 /// Stateless codecs should use the default `0`.
104 const MAX_ENCODE_RESET_UNITS: usize = 0;
105
106 /// The maximum unit count emitted when flushing encode state at EOF.
107 ///
108 /// Stateless codecs should use the default `0`. Codecs that emit a
109 /// stream trailer (padding, checksum, or end-of-stream marker) should
110 /// override this with the exact maximum unit count.
111 const MAX_ENCODE_FLUSH_UNITS: usize = 0;
112
113 /// The maximum value count emitted when resetting decode state.
114 ///
115 /// Stateless codecs should use the default `0`. Codecs that emit a
116 /// stream-start sentinel or BOM on reset should override this.
117 const MAX_DECODE_RESET_VALUES: usize = 0;
118
119 /// The maximum value count emitted when flushing decode state.
120 ///
121 /// Stateless codecs should use the default `0`.
122 const MAX_DECODE_FLUSH_VALUES: usize = 0;
123
124 /// Returns whether `value` is in this codec's encodable value domain.
125 ///
126 /// The default implementation returns `true`, which is correct for codecs
127 /// whose [`Value`](Self::Value) type contains only values they can encode.
128 /// Codecs whose logical value type is broader than their representation
129 /// domain, such as an ASCII codec with `Value = char`, must override this
130 /// method.
131 ///
132 /// Checked encoder adapters call this method before querying
133 /// [`encode_len`](Self::encode_len) or entering the unsafe
134 /// [`encode`](Self::encode) method. Direct unsafe callers must do the same.
135 ///
136 /// # Parameters
137 ///
138 /// - `value`: Value whose encodability is queried.
139 ///
140 /// # Returns
141 ///
142 /// Returns `true` when `value` may be passed to
143 /// [`encode_len`](Self::encode_len) and [`encode`](Self::encode).
144 #[inline(always)]
145 #[must_use]
146 fn can_encode_value(&self, _value: &Self::Value) -> bool {
147 true
148 }
149
150 /// Returns the exact non-zero unit count this codec will write when
151 /// encoding `value`.
152 ///
153 /// The default implementation returns
154 /// [`MAX_UNITS_PER_VALUE`](Self::MAX_UNITS_PER_VALUE), which is the
155 /// conservative bound callers can use when no specific value is available.
156 /// Fixed-width codecs do not need to override this method.
157 ///
158 /// Variable-width codecs (LEB128, UTF-8, GB18030, …) should override this
159 /// to report the true encoded length for encodable `value`s. Doing so lets
160 /// buffered adapters and stream writers reserve only what is actually
161 /// needed and enables capacity probing without performing the encode.
162 /// Default codec-backed encoders use this exact value for per-value output
163 /// capacity. The contract requires callers to use this method only when
164 /// [`can_encode_value`](Self::can_encode_value) returned `true` for the
165 /// same `value`. Under that precondition, the returned length must equal
166 /// the unit count [`encode`](Self::encode) writes for the same `value`
167 /// under the same codec state, and must never exceed
168 /// [`MAX_UNITS_PER_VALUE`](Self::MAX_UNITS_PER_VALUE).
169 ///
170 /// # Parameters
171 ///
172 /// - `value`: Value whose encoded length is queried.
173 ///
174 /// # Returns
175 ///
176 /// Returns the non-zero unit count [`encode`](Self::encode) will write for
177 /// an encodable `value`.
178 #[inline(always)]
179 #[must_use]
180 fn encode_len(&self, _value: &Self::Value) -> NonZeroUsize {
181 Self::MAX_UNITS_PER_VALUE
182 }
183
184 /// Emits stream-start output and resets encode-side state.
185 ///
186 /// # Parameters
187 ///
188 /// - `output`: Destination unit buffer.
189 /// - `output_index`: Start index in `output`.
190 ///
191 /// # Returns
192 ///
193 /// Returns the number of reset units written.
194 ///
195 /// # Errors
196 ///
197 /// Returns `Self::EncodeError` when reset output cannot be emitted.
198 /// Implementations must leave their internal state consistent when
199 /// returning an error.
200 ///
201 /// # Safety
202 ///
203 /// The caller must guarantee that the implementation can write up to
204 /// [`MAX_ENCODE_RESET_UNITS`](Self::MAX_ENCODE_RESET_UNITS) units starting
205 /// at `output_index`.
206 #[inline(always)]
207 #[must_use = "reset output and reset errors must be handled"]
208 unsafe fn encode_reset(
209 &mut self,
210 _output: &mut [Self::Unit],
211 _output_index: usize,
212 ) -> Result<usize, Self::EncodeError> {
213 Ok(0)
214 }
215
216 /// Encodes one borrowed value into `output` starting at `output_index`.
217 ///
218 /// # Parameters
219 ///
220 /// - `value`: Value to encode.
221 /// - `output`: Destination unit buffer.
222 /// - `output_index`: Start index in `output`.
223 ///
224 /// # Returns
225 ///
226 /// Returns the non-zero number of written units. A successful encode
227 /// always emits at least one unit; stateful encoders that need to defer
228 /// output should report that intent through a custom encode error
229 /// instead of returning a zero count.
230 ///
231 /// # Errors
232 ///
233 /// Returns `Self::EncodeError` for encode-side state or representation
234 /// failures other than a value being outside the codec's encodable domain.
235 /// Checked callers reject values for which
236 /// [`can_encode_value`](Self::can_encode_value) returns `false` before
237 /// entering this unsafe method. Implementations must leave their internal
238 /// state consistent when returning an error.
239 ///
240 /// # Safety
241 ///
242 /// The caller must guarantee that
243 /// [`can_encode_value`](Self::can_encode_value) returned `true` for
244 /// `value`, and that the implementation can write at least
245 /// [`encode_len`](Self::encode_len) units for the same `value` and codec
246 /// state starting at `output_index`. On success, implementations must
247 /// return that exact written unit count, and the count must be no
248 /// larger than [`MAX_UNITS_PER_VALUE`](Self::MAX_UNITS_PER_VALUE).
249 #[must_use = "encoded length and encode errors must be handled"]
250 unsafe fn encode(
251 &mut self,
252 value: &Self::Value,
253 output: &mut [Self::Unit],
254 output_index: usize,
255 ) -> Result<NonZeroUsize, Self::EncodeError>;
256
257 /// Emits EOF trailer output and flushes encode-side state.
258 ///
259 /// This is the encode-side counterpart of
260 /// [`decode_flush`](Self::decode_flush). Codecs that append stream
261 /// trailers (padding, checksums, end-of-stream markers) emit them here.
262 /// Stateless codecs use the default no-op.
263 ///
264 /// # Parameters
265 ///
266 /// - `output`: Destination unit buffer.
267 /// - `output_index`: Start index in `output`.
268 ///
269 /// # Returns
270 ///
271 /// Returns the number of flush units written.
272 ///
273 /// # Errors
274 ///
275 /// Returns `Self::EncodeError` when flush output cannot be emitted.
276 /// Implementations must leave their internal state consistent when
277 /// returning an error.
278 ///
279 /// # Safety
280 ///
281 /// The caller must guarantee that the implementation can write up to
282 /// [`MAX_ENCODE_FLUSH_UNITS`](Self::MAX_ENCODE_FLUSH_UNITS) units starting
283 /// at `output_index`.
284 #[inline(always)]
285 #[must_use = "flush output and flush errors must be handled"]
286 unsafe fn encode_flush(
287 &mut self,
288 _output: &mut [Self::Unit],
289 _output_index: usize,
290 ) -> Result<usize, Self::EncodeError> {
291 Ok(0)
292 }
293
294 /// Emits stream-start values and resets decode-side state.
295 ///
296 /// This is the decode-side counterpart of
297 /// [`encode_reset`](Self::encode_reset). Codecs that emit a
298 /// stream-start marker or BOM before decoding a new stream emit them
299 /// here. Stateless codecs use the default no-op.
300 ///
301 /// # Parameters
302 ///
303 /// - `output`: Destination value buffer.
304 /// - `output_index`: Start index in `output`.
305 ///
306 /// # Returns
307 ///
308 /// Returns the number of reset values written.
309 ///
310 /// # Errors
311 ///
312 /// Returns `Self::DecodeError` when reset output cannot be emitted.
313 /// Implementations must leave their internal state consistent when
314 /// returning an error.
315 ///
316 /// # Safety
317 ///
318 /// The caller must guarantee that the implementation can write up to
319 /// [`MAX_DECODE_RESET_VALUES`](Self::MAX_DECODE_RESET_VALUES) values
320 /// starting at `output_index`.
321 #[inline(always)]
322 #[must_use = "reset output and reset errors must be handled"]
323 unsafe fn decode_reset(
324 &mut self,
325 _output: &mut [Self::Value],
326 _output_index: usize,
327 ) -> Result<usize, Self::DecodeError> {
328 Ok(0)
329 }
330
331 /// Decodes one value from `input` starting at `input_index`.
332 ///
333 /// # Parameters
334 ///
335 /// - `input`: Source unit buffer.
336 /// - `input_index`: Start index in `input`.
337 ///
338 /// # Returns
339 ///
340 /// Returns the decoded value and the non-zero number of consumed units.
341 ///
342 /// # Errors
343 ///
344 /// Returns [`DecodeFailure::Incomplete`] when the visible input is a
345 /// valid prefix but more units are needed to decide or complete a value.
346 /// This reports a streaming boundary, not a final EOF condition; the
347 /// caller or higher-level adapter decides what an incomplete tail means
348 /// when the upstream source is closed.
349 /// Returns [`DecodeFailure::Invalid`] when the units are malformed,
350 /// non-canonical, unmappable, or otherwise invalid for this codec. The
351 /// concrete error type carries only codec-domain invalidity.
352 /// Implementations must leave their internal state consistent when
353 /// returning an error.
354 ///
355 /// # Safety
356 ///
357 /// The caller must guarantee that `input_index` is a valid boundary in
358 /// `input` and that at least
359 /// [`MIN_UNITS_PER_VALUE`](Self::MIN_UNITS_PER_VALUE)
360 /// units are readable from `input_index`. Implementations must not read
361 /// beyond the currently available units under that precondition. They
362 /// may return [`DecodeFailure::Incomplete`] when those units are a
363 /// valid but incomplete prefix.
364 ///
365 /// On success, implementations must return a consumed unit count no larger
366 /// than the available input. The return type guarantees that successful
367 /// decoding always consumes at least one unit. Implementations should use
368 /// `debug_assert!` to state these unchecked entry-point assumptions.
369 #[must_use = "decoded value, consumed length, and decode errors must be handled"]
370 unsafe fn decode(
371 &mut self,
372 input: &[Self::Unit],
373 input_index: usize,
374 ) -> Result<(Self::Value, NonZeroUsize), DecodeFailure<Self::DecodeError>>;
375
376 /// Flushes decode-side EOF state into `output`.
377 ///
378 /// `decode_flush` receives no source input. Callers must have already
379 /// handled any tail reported by [`DecodeFailure::Incomplete`] before
380 /// flushing decode state. Implementations may emit retained values or
381 /// validate internal EOF state, but they must not depend on re-reading the
382 /// incomplete source tail.
383 ///
384 /// # Parameters
385 ///
386 /// - `output`: Destination value buffer.
387 /// - `output_index`: Start index in `output`.
388 ///
389 /// # Returns
390 ///
391 /// Returns the number of flushed values written.
392 ///
393 /// # Errors
394 ///
395 /// Returns `Self::DecodeError` when retained decode state is invalid at
396 /// EOF. Implementations must leave their internal state consistent when
397 /// returning an error.
398 ///
399 /// # Safety
400 ///
401 /// The caller must guarantee that the implementation can write up to
402 /// [`MAX_DECODE_FLUSH_VALUES`](Self::MAX_DECODE_FLUSH_VALUES) values
403 /// starting at `output_index`.
404 #[inline(always)]
405 #[must_use = "flush output length and flush errors must be handled"]
406 unsafe fn decode_flush(
407 &mut self,
408 _output: &mut [Self::Value],
409 _output_index: usize,
410 ) -> Result<usize, Self::DecodeError> {
411 Ok(0)
412 }
413}
414
415/// Compile-time asserts the public unit-bound invariant required by [`Codec`].
416///
417/// # Type Parameters
418///
419/// - `C`: Codec implementation to validate.
420///
421/// # Returns
422///
423/// Returns unit `()`.
424///
425/// # Panics
426///
427/// Panics at compile time when [`Codec::MIN_UNITS_PER_VALUE`] is greater than
428/// [`Codec::MAX_UNITS_PER_VALUE`], because the invariant must hold for any
429/// well-formed [`Codec`] implementation and violating it is always a bug.
430#[inline(always)]
431pub(crate) fn assert_unit_bounds<C>()
432where
433 C: Codec,
434{
435 const {
436 assert!(
437 C::MIN_UNITS_PER_VALUE.get() <= C::MAX_UNITS_PER_VALUE.get(),
438 "Codec::MIN_UNITS_PER_VALUE must not exceed Codec::MAX_UNITS_PER_VALUE",
439 );
440 }
441}