Skip to main content

qubit_codec/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
9use core::num::NonZeroUsize;
10
11use super::super::decode_failure::DecodeFailure;
12
13/// Encodes and decodes one value or codec quantum against a unit buffer.
14///
15/// `Codec` is the lowest-level abstraction in the codec stack. It is intended
16/// for hot paths that have already validated buffer capacity and want to avoid
17/// constructing subslices for every value. Higher-level transcoders and
18/// convenience APIs are responsible for checked buffer management and owned
19/// output allocation.
20///
21/// `MIN_UNITS_PER_VALUE` and `MAX_DECODE_UNITS_PER_VALUE` describe the readable
22/// representation-width bounds for one decoded value. If fewer than the
23/// minimum units are available, no complete value can exist, so a streaming
24/// caller can request more input or report an incomplete EOF tail. The minimum
25/// is also the smallest safety precondition checked callers must satisfy before
26/// entering [`decode`](Self::decode). The decode maximum bounds successful
27/// consumption and incomplete-input requirements for one value.
28///
29/// `MAX_ENCODE_UNITS_PER_VALUE` is the independent value-agnostic upper bound
30/// for main-phase encode output. Reserving that many units makes encoding safe
31/// for every encodable value. Once a value and encode state are known, callers
32/// may instead reserve the exact [`encode_len`](Self::encode_len), which must
33/// not exceed the encode maximum. Complete-lifecycle adapters that still need
34/// to run [`encode_reset`](Self::encode_reset) must reserve the maximum first
35/// because reset may change the exact width.
36///
37/// A codec may keep decode-side and encode-side stream state. That state is an
38/// implementation detail owned by the codec. Callers do not snapshot or restore
39/// it; implementations must keep their own state internally consistent across
40/// every public operation. A failed decode attempt must not advance decode
41/// state, so callers can retry the same input after refilling their buffer or
42/// applying an invalid-input policy.
43///
44/// Decode operations see only the currently supplied input slice and codec
45/// state. [`decode`](Self::decode) treats that slice as an open stream segment;
46/// [`decode_eof`](Self::decode_eof) receives the same preconditions after the
47/// caller has established that no more units will arrive. Returning
48/// [`DecodeFailure::Incomplete`] from `decode` requests more input for the
49/// current value; it is not itself an EOF error. Codecs that need EOF-aware
50/// maximal-munch parsing or reinterpretation of a trailing prefix can override
51/// `decode_eof` without changing their streaming behavior.
52/// An incomplete failure may also retain codec-specific context through
53/// [`DecodeFailure::incomplete_with_source`]; stream drivers may ignore that
54/// context while retrying and use it for detailed EOF diagnostics.
55///
56/// # Associated Types
57///
58/// - `Value`: Logical value decoded from or encoded into the buffer. This may
59///   be a scalar such as `u8`, `u16`, `u64`, a `char`, a fixed quantum such as
60///   `[u8; 3]`, or an owned value such as `String`/`Vec<u8>`. Adapters that
61///   need scratch initialization add their own bounds at the use site.
62/// - `Unit`: Buffer unit used by the encoded representation. Implementations
63///   are typically scalar storage units such as `u8`, `u16`, or `char`.
64///   Adapters that allocate owned output add their own initialization bounds at
65///   the use site.
66///
67/// Implementors must uphold the safety contract documented by
68/// [`decode`](Self::decode), [`encode`](Self::encode),
69/// [`encode_reset`](Self::encode_reset), and
70/// [`decode_finish`](Self::decode_finish). Unchecked implementations must not
71/// read or write outside the caller-provided ranges. Implementations should use
72/// `debug_assert!` to state the expected buffer bounds at the unchecked entry
73/// point.
74///
75/// Implementations must also guarantee that
76/// [`MIN_UNITS_PER_VALUE`](Self::MIN_UNITS_PER_VALUE) is non-zero and no larger
77/// than [`MAX_DECODE_UNITS_PER_VALUE`](Self::MAX_DECODE_UNITS_PER_VALUE), which
78/// must also be non-zero. `MAX_ENCODE_UNITS_PER_VALUE` may be zero for a codec
79/// that always buffers each accepted value instead of immediately emitting
80/// units. Checked adapters enforce the decode-bound invariants with
81/// compile-time assertions before using codec-provided bounds.
82///
83/// # Why the low-level methods are unchecked
84///
85/// The `unsafe` entry points are intentional: checked adapters validate the
86/// index and capacity preconditions once, then call [`encode`](Self::encode)
87/// and [`decode`](Self::decode) without rebuilding subslices or repeating
88/// bounds checks for every value. The `safe_vs_unchecked` benchmark in
89/// `benches/transcode.rs` compares the same 64 KiB copy loop in release mode.
90/// Its result is workload- and toolchain-specific, so callers should use
91/// checked adapters unless they can establish the documented preconditions at
92/// a trusted boundary. Measure representative codec workloads before choosing
93/// an unchecked entry point. Codec implementations should keep the unchecked
94/// methods small and use `debug_assert!` for those assumptions.
95///
96/// # Examples
97///
98/// A minimal identity codec exposes its bounds and decodes one byte:
99///
100/// ```
101/// use core::convert::Infallible;
102/// use core::num::NonZeroUsize;
103///
104/// use qubit_codec::Codec;
105/// use qubit_codec::DecodeFailure;
106///
107/// struct Identity;
108/// impl Identity {
109///     fn new() -> Self { Self }
110/// }
111/// impl Codec for Identity {
112///     type Value = u8;
113///     type Unit = u8;
114///     type DecodeError = Infallible;
115///     type EncodeError = Infallible;
116///     const MIN_UNITS_PER_VALUE: usize = 1;
117///     const MAX_DECODE_UNITS_PER_VALUE: usize = 1;
118///     const MAX_ENCODE_UNITS_PER_VALUE: usize = 1;
119///
120///     unsafe fn decode(&mut self, input: &[u8], index: usize)
121///         -> Result<(u8, NonZeroUsize), DecodeFailure<Infallible>> {
122///         Ok((input[index], NonZeroUsize::MIN))
123///     }
124///
125///     unsafe fn encode(&mut self, value: &u8, output: &mut [u8], index: usize)
126///         -> Result<usize, Infallible> {
127///         output[index] = *value;
128///         Ok(1)
129///     }
130/// }
131///
132/// let mut codec = Identity::new();
133/// assert_eq!(codec.encode_len(&42), 1);
134/// // SAFETY: the input contains the one readable unit required by Identity.
135/// let (value, consumed) = unsafe { codec.decode(&[42], 0) }.unwrap();
136/// assert_eq!((value, consumed.get()), (42, 1));
137/// ```
138pub trait Codec {
139    /// The type of logical values decoded from or encoded into the buffer.
140    type Value;
141
142    /// The type of buffer units used by the encoded representation.
143    type Unit;
144
145    /// The type of errors reported when decoding malformed units.
146    type DecodeError;
147
148    /// The type of errors reported when encoding an unsupported value.
149    type EncodeError;
150
151    /// The minimum possible non-zero readable unit count for one decoded value.
152    ///
153    /// This is a lower bound used by checked callers for planning and fast
154    /// impossibility checks. If a streaming decoder has fewer than this many
155    /// readable units, no complete value can be present at the current
156    /// position. It is also the denominator used by default decode hooks when
157    /// estimating the maximum number of values that can be produced from an
158    /// input unit count.
159    const MIN_UNITS_PER_VALUE: usize;
160
161    /// The maximum unit count emitted when encoding one value.
162    ///
163    /// This is a value-independent upper bound for the main encode phase. When
164    /// no concrete value is available, reserving this many writable units is
165    /// sufficient for any encodable value, without first calling
166    /// [`encode_len`](Self::encode_len). For a known value, callers may reserve
167    /// only the exact length returned by `encode_len` instead. This bound does
168    /// not include output produced by encode reset or finish phases.
169    ///
170    /// This is also the multiplier used by default encode hooks when estimating
171    /// the maximum number of output units needed for an input value count.
172    ///
173    /// The bound may be zero for a codec that buffers every accepted value and
174    /// emits retained output only during a later lifecycle phase.
175    const MAX_ENCODE_UNITS_PER_VALUE: usize;
176
177    /// The maximum non-zero unit count consumed to decode one value.
178    ///
179    /// This is a value-independent upper bound for one complete encoded value
180    /// or codec quantum on the decode side. Successful decode consumption and
181    /// the `required_total` carried by [`DecodeFailure::Incomplete`] must not
182    /// exceed this bound.
183    const MAX_DECODE_UNITS_PER_VALUE: usize;
184
185    /// The maximum unit count emitted when resetting encode state.
186    ///
187    /// This bound covers only output written by
188    /// [`encode_reset`](Self::encode_reset). It does not include hook-owned
189    /// reset output or any ordinary encoded input values. It must cover every
190    /// reachable pre-reset encode state. Stateless codecs should use the
191    /// default `0`.
192    const MAX_ENCODE_RESET_UNITS: usize = 0;
193
194    /// The maximum unit count emitted when finishing encode state at EOF.
195    ///
196    /// This bound covers only output written by
197    /// [`encode_finish`](Self::encode_finish). It does not include hook-owned
198    /// finish output and must cover every reachable encode state, even when the
199    /// current stream has no pending finish output. Stateless codecs should use
200    /// the default `0`. Codecs that emit a stream trailer (padding, checksum,
201    /// or end-of-stream marker) should override this with the exact maximum
202    /// unit count.
203    const MAX_ENCODE_FINISH_UNITS: usize = 0;
204
205    /// The maximum value count emitted when resetting decode state.
206    ///
207    /// This bound covers only values written by
208    /// [`decode_reset`](Self::decode_reset). It does not include hook-owned
209    /// reset output or values decoded from source units. It must cover every
210    /// reachable pre-reset decode state. Stateless codecs should use the
211    /// default `0`. Codecs that emit a stream-start sentinel or BOM on reset
212    /// should override this.
213    const MAX_DECODE_RESET_VALUES: usize = 0;
214
215    /// The maximum value count emitted when finishing decode state.
216    ///
217    /// This bound covers only values written by
218    /// [`decode_finish`](Self::decode_finish). It does not include hook-owned
219    /// finish output and must cover every reachable decode state, even when the
220    /// current stream has no pending finish output. Stateless codecs should use
221    /// the default `0`.
222    const MAX_DECODE_FINISH_VALUES: usize = 0;
223
224    /// Returns whether `value` is in this codec's encodable value domain.
225    ///
226    /// The default implementation returns `true`, which is correct for codecs
227    /// whose [`Value`](Self::Value) type contains only values they can encode.
228    /// Codecs whose logical value type is broader than their representation
229    /// domain, such as an ASCII codec with `Value = char`, must override this
230    /// method.
231    ///
232    /// Checked encoder adapters call this method in the same codec state used
233    /// to query [`encode_len`](Self::encode_len) and enter the unsafe
234    /// [`encode`](Self::encode) method. Complete-lifecycle adapters do so after
235    /// [`encode_reset`](Self::encode_reset). Direct unsafe callers must uphold
236    /// the same ordering.
237    ///
238    /// # Parameters
239    ///
240    /// - `value`: Value whose encodability is queried.
241    ///
242    /// # Returns
243    ///
244    /// Returns `true` when `value` may be passed to
245    /// [`encode_len`](Self::encode_len) and [`encode`](Self::encode).
246    #[inline]
247    #[must_use]
248    fn can_encode_value(&self, _value: &Self::Value) -> bool {
249        true
250    }
251
252    /// Returns the exact unit count this codec will write when encoding
253    /// `value`.
254    ///
255    /// The default implementation returns
256    /// [`MAX_ENCODE_UNITS_PER_VALUE`](Self::MAX_ENCODE_UNITS_PER_VALUE). This
257    /// default is correct only when every successful main encode writes exactly
258    /// that many units in the relevant codec state, as fixed-width codecs
259    /// normally do.
260    ///
261    /// Variable-width, buffering, or otherwise state-dependent codecs must
262    /// override this method to report the true encoded length for encodable
263    /// `value`s. The return value is never an estimate or an "unknown" marker:
264    /// it must equal the unit count [`encode`](Self::encode) subsequently
265    /// writes for the same `value` under the same codec state. It must also
266    /// never exceed
267    /// [`MAX_ENCODE_UNITS_PER_VALUE`](Self::MAX_ENCODE_UNITS_PER_VALUE).
268    /// Callers that do not yet have a concrete value should use
269    /// `MAX_ENCODE_UNITS_PER_VALUE` directly instead of calling this method.
270    ///
271    /// Default codec-backed encoders use this exact value for per-value output
272    /// capacity. The contract requires callers to use this method only when
273    /// [`can_encode_value`](Self::can_encode_value) returned `true` for the
274    /// same `value`.
275    ///
276    /// # Parameters
277    ///
278    /// - `value`: Value whose encoded length is queried.
279    ///
280    /// # Returns
281    ///
282    /// Returns the unit count [`encode`](Self::encode) will write for an
283    /// encodable `value`.
284    ///
285    /// A return value of `0` is valid for stateful encoders that accept a
286    /// value into internal state without immediately emitting units. Examples
287    /// include codecs that aggregate values into fixed-size quanta, shift-state
288    /// encodings, or framing layers that defer output until enough values have
289    /// been seen or EOF is finalized. Stateless and directly value-to-unit
290    /// codecs should continue returning a positive length.
291    #[inline]
292    #[must_use]
293    fn encode_len(&self, _value: &Self::Value) -> usize {
294        Self::MAX_ENCODE_UNITS_PER_VALUE
295    }
296
297    /// Emits stream-start output and resets encode-side state.
298    ///
299    /// # Parameters
300    ///
301    /// - `output`: Destination unit buffer.
302    /// - `output_index`: Start index in `output`.
303    ///
304    /// # Returns
305    ///
306    /// Returns the number of reset units written.
307    ///
308    /// # Errors
309    ///
310    /// Returns `Self::EncodeError` when reset output cannot be emitted.
311    /// Implementations must leave encode state unchanged when returning an
312    /// error.
313    ///
314    /// # Safety
315    ///
316    /// The caller must guarantee that the implementation can write up to
317    /// [`MAX_ENCODE_RESET_UNITS`](Self::MAX_ENCODE_RESET_UNITS) units starting
318    /// at `output_index`.
319    #[inline]
320    unsafe fn encode_reset(
321        &mut self,
322        _output: &mut [Self::Unit],
323        _output_index: usize,
324    ) -> Result<usize, Self::EncodeError> {
325        Ok(0)
326    }
327
328    /// Encodes one borrowed value into `output` starting at `output_index`.
329    ///
330    /// # Parameters
331    ///
332    /// - `value`: Value to encode.
333    /// - `output`: Destination unit buffer.
334    /// - `output_index`: Start index in `output`.
335    ///
336    /// # Returns
337    ///
338    /// Returns the number of written units.
339    ///
340    /// A successful encode may return `0` when the codec accepted `value` into
341    /// internal encode-side state but intentionally deferred output. This is
342    /// the normal shape for accumulative encoders such as base64-byte
343    /// aggregators, shift-state encodings, or frame builders. In that case
344    /// [`encode_len`](Self::encode_len) for the same `value` and state must
345    /// also return `0`, and the retained output must be emitted by a later
346    /// successful [`encode`](Self::encode),
347    /// [`encode_finish`](Self::encode_finish), or codec-specific facade.
348    ///
349    /// # Errors
350    ///
351    /// Returns `Self::EncodeError` for encode-side state or representation
352    /// failures other than a value being outside the codec's encodable domain.
353    /// Checked callers reject values for which
354    /// [`can_encode_value`](Self::can_encode_value) returns `false` before
355    /// entering this unsafe method. Implementations must leave their internal
356    /// state consistent when returning an error.
357    ///
358    /// # Safety
359    ///
360    /// The caller must guarantee that
361    /// [`can_encode_value`](Self::can_encode_value) returned `true` for
362    /// `value`. Starting at `output_index`, the caller must also provide either
363    /// at least
364    /// [`MAX_ENCODE_UNITS_PER_VALUE`](Self::MAX_ENCODE_UNITS_PER_VALUE)
365    /// writable
366    /// units, which is sufficient for every encodable value, or at least the
367    /// exact [`encode_len`](Self::encode_len) for the same `value` and codec
368    /// state. On success, implementations must return that exact written unit
369    /// count, including `0` for deliberate buffering, and the count must be no
370    /// larger than `MAX_ENCODE_UNITS_PER_VALUE`. Implementations must not write
371    /// beyond the exact `encode_len` capacity on either the success or error
372    /// path.
373    unsafe fn encode(
374        &mut self,
375        value: &Self::Value,
376        output: &mut [Self::Unit],
377        output_index: usize,
378    ) -> Result<usize, Self::EncodeError>;
379
380    /// Emits EOF trailer output and finishes encode-side state.
381    ///
382    /// This is the encode-side counterpart of
383    /// [`decode_finish`](Self::decode_finish). Codecs that append stream
384    /// trailers (padding, checksums, end-of-stream markers) emit them here.
385    /// Stateless codecs use the default no-op.
386    ///
387    /// # Parameters
388    ///
389    /// - `output`: Destination unit buffer.
390    /// - `output_index`: Start index in `output`.
391    ///
392    /// # Returns
393    ///
394    /// Returns the number of finish units written.
395    ///
396    /// # Errors
397    ///
398    /// Returns `Self::EncodeError` when finish output cannot be emitted.
399    /// Implementations must leave their internal state consistent when
400    /// returning an error.
401    ///
402    /// # Safety
403    ///
404    /// The caller must guarantee that the implementation can write up to
405    /// [`MAX_ENCODE_FINISH_UNITS`](Self::MAX_ENCODE_FINISH_UNITS) units
406    /// starting at `output_index`.
407    #[inline]
408    unsafe fn encode_finish(
409        &mut self,
410        _output: &mut [Self::Unit],
411        _output_index: usize,
412    ) -> Result<usize, Self::EncodeError> {
413        Ok(0)
414    }
415
416    /// Emits stream-start values and resets decode-side state.
417    ///
418    /// This is the decode-side counterpart of
419    /// [`encode_reset`](Self::encode_reset). Codecs that emit a
420    /// stream-start marker or BOM before decoding a new stream emit them
421    /// here. Stateless codecs use the default no-op.
422    ///
423    /// # Parameters
424    ///
425    /// - `output`: Destination value buffer.
426    /// - `output_index`: Start index in `output`.
427    ///
428    /// # Returns
429    ///
430    /// Returns the number of reset values written.
431    ///
432    /// # Errors
433    ///
434    /// Returns `Self::DecodeError` when reset output cannot be emitted.
435    /// Implementations must leave their internal state consistent when
436    /// returning an error.
437    ///
438    /// # Safety
439    ///
440    /// The caller must guarantee that the implementation can write up to
441    /// [`MAX_DECODE_RESET_VALUES`](Self::MAX_DECODE_RESET_VALUES) values
442    /// starting at `output_index`.
443    #[inline]
444    unsafe fn decode_reset(
445        &mut self,
446        _output: &mut [Self::Value],
447        _output_index: usize,
448    ) -> Result<usize, Self::DecodeError> {
449        Ok(0)
450    }
451
452    /// Decodes one value from `input` starting at `input_index`.
453    ///
454    /// # Parameters
455    ///
456    /// - `input`: Source unit buffer.
457    /// - `input_index`: Start index in `input`.
458    ///
459    /// # Returns
460    ///
461    /// Returns the decoded value and the non-zero number of consumed units.
462    ///
463    /// # Errors
464    ///
465    /// Returns [`DecodeFailure::Incomplete`] when the visible input is a
466    /// valid prefix but more units are needed to decide or complete a value.
467    /// This reports a streaming boundary, not a final EOF condition; the
468    /// caller or higher-level adapter decides what an incomplete tail means
469    /// when the upstream source is closed. Codec-specific context may be
470    /// retained in the failure's optional `source` field.
471    /// Returns [`DecodeFailure::Invalid`] when the units are malformed,
472    /// non-canonical, unmappable, or otherwise invalid for this codec and the
473    /// span is known or unknown. Unknown span is represented as
474    /// [`DecodeFailure::Invalid`] with an unknown consumed-unit hint.
475    /// Implementations must leave their internal state consistent when
476    /// returning an error.
477    ///
478    /// # Safety
479    ///
480    /// The caller must guarantee that `input_index` is a valid boundary in
481    /// `input` and that at least
482    /// [`MIN_UNITS_PER_VALUE`](Self::MIN_UNITS_PER_VALUE)
483    /// units are readable from `input_index`. Implementations must not read
484    /// beyond the currently available units under that precondition. They
485    /// may return [`DecodeFailure::Incomplete`] when those units are a
486    /// valid but incomplete prefix.
487    ///
488    /// On success, implementations must return a consumed unit count no larger
489    /// than either the available input or
490    /// [`MAX_DECODE_UNITS_PER_VALUE`](Self::MAX_DECODE_UNITS_PER_VALUE). An
491    /// incomplete result's `required_total` must also not exceed that maximum.
492    /// The return type guarantees that successful decoding always consumes at
493    /// least one unit. Implementations should use `debug_assert!` to state
494    /// these unchecked entry-point assumptions.
495    unsafe fn decode(
496        &mut self,
497        input: &[Self::Unit],
498        input_index: usize,
499    ) -> Result<(Self::Value, NonZeroUsize), DecodeFailure<Self::DecodeError>>;
500
501    /// Decodes one value after the caller has established end of input.
502    ///
503    /// This method has the same safety and state guarantees as
504    /// [`decode`](Self::decode), but may resolve an otherwise incomplete
505    /// trailing prefix using EOF-aware format rules. The default preserves the
506    /// open-stream behavior by delegating to [`decode`](Self::decode).
507    ///
508    /// # Parameters
509    ///
510    /// - `input`: Final source unit buffer; no more units will arrive.
511    /// - `input_index`: Start index of the value in `input`.
512    ///
513    /// # Returns
514    ///
515    /// Returns the decoded value and the non-zero number of consumed units.
516    ///
517    /// # Errors
518    ///
519    /// Returns [`DecodeFailure::Incomplete`] for an unresolved final prefix,
520    /// or [`DecodeFailure::Invalid`] for malformed input, as in
521    /// [`decode`](Self::decode). An override may resolve a prefix at EOF.
522    ///
523    /// # Safety
524    ///
525    /// The caller must satisfy the same input-index and minimum-readable-unit
526    /// preconditions as [`decode`](Self::decode). Implementations must not
527    /// read beyond the currently available units.
528    #[inline]
529    unsafe fn decode_eof(
530        &mut self,
531        input: &[Self::Unit],
532        input_index: usize,
533    ) -> Result<(Self::Value, NonZeroUsize), DecodeFailure<Self::DecodeError>> {
534        // SAFETY: `decode_eof` has the same preconditions as `decode`.
535        unsafe { self.decode(input, input_index) }
536    }
537
538    /// Finishes decode-side EOF state into `output`.
539    ///
540    /// `decode_finish` receives no source input. Callers must have already
541    /// handled any tail reported by [`DecodeFailure::Incomplete`] before
542    /// finishing decode state. Implementations may emit retained values or
543    /// validate internal EOF state, but they must not depend on re-reading the
544    /// incomplete source tail.
545    ///
546    /// # Parameters
547    ///
548    /// - `output`: Destination value buffer.
549    /// - `output_index`: Start index in `output`.
550    ///
551    /// # Returns
552    ///
553    /// Returns the number of finished values written.
554    ///
555    /// # Errors
556    ///
557    /// Returns `Self::DecodeError` when retained decode state is invalid at
558    /// EOF. Implementations must leave their internal state consistent when
559    /// returning an error.
560    ///
561    /// # Safety
562    ///
563    /// The caller must guarantee that the implementation can write up to
564    /// [`MAX_DECODE_FINISH_VALUES`](Self::MAX_DECODE_FINISH_VALUES) values
565    /// starting at `output_index`.
566    #[inline]
567    unsafe fn decode_finish(
568        &mut self,
569        _output: &mut [Self::Value],
570        _output_index: usize,
571    ) -> Result<usize, Self::DecodeError> {
572        Ok(0)
573    }
574}