Skip to main content

qubit_codec/
lib.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//! # qubit-codec
9//!
10//! Domain-neutral codec traits and buffer conversion primitives.
11//!
12//! `qubit-codec` is the foundation shared by the Qubit binary, text, misc, and
13//! I/O codec crates. It defines the small contracts that concrete format crates
14//! build on, without shipping concrete binary or text formats itself.
15//!
16//! # Overview
17//!
18//! The crate provides:
19//!
20//! - [`Codec`] for low-level single-value codecs over caller-managed buffers.
21//! - [`CodecValueEncoder`] and [`CodecValueDecoder`] for owned one-value
22//!   convenience APIs.
23//! - [`CodecTranscodeEncoder`], [`CodecTranscodeDecoder`], and
24//!   [`CodecTranscodeConverter`] for strict streaming adapters around a
25//!   [`Codec`].
26//! - [`engine::TranscodeEncodeEngine`], [`engine::TranscodeDecodeEngine`], and
27//!   [`engine::TranscodeConvertEngine`] for policy-aware buffered loops.
28//! - [`engine::TranscodeEncodeHooks`] and [`engine::TranscodeDecodeHooks`] for
29//!   replacement, skip, report, finish, and reset policy decisions.
30//! - [`Transcoder`], [`TranscodeProgress`], and [`TranscodeStatus`] for
31//!   caller-managed streaming conversion.
32//! - [`ValueEncoder`] and [`ValueDecoder`] for whole-value convenience APIs.
33//! - [`ByteOrder`], [`ByteOrderSpec`], [`BigEndian`], [`LittleEndian`], and
34//!   [`NativeEndian`] for shared byte-order metadata.
35//! - [`nz()`] and [`nz!`] for checked `NonZeroUsize` construction shared by
36//!   codec implementations.
37//!
38//! Concrete codecs live in sibling crates such as `qubit-codec-binary`,
39//! `qubit-codec-text`, and `qubit-codec-misc`.
40//!
41//! # Choosing an Abstraction
42//!
43//! Pick the smallest layer that matches the shape of the problem:
44//!
45//! ```text
46//! What are you writing?
47//!
48//! +-- A codec for one logical value
49//! |   (UTF-8 char, LEB128 integer, fixed-width scalar, ...)
50//! |       -> implement Codec
51//! |
52//! +-- A whole-value codec where a single-value quantum is not useful
53//! |   (Base64 text, percent encoding, escaped strings, ...)
54//! |       -> implement ValueEncoder<Input> / ValueDecoder<Input>
55//! |
56//! +-- A strict streaming wrapper around an existing Codec
57//! |       -> use CodecTranscodeDecoder<C> / CodecTranscodeEncoder<C>
58//! |          / CodecTranscodeConverter<D, E>
59//! |
60//! +-- An owned-output wrapper around an existing Codec
61//! |       -> use CodecValueEncoder<C> / CodecValueDecoder<C>
62//! |
63//! +-- A streaming codec with policy decisions
64//!     (skip, replace, count, report, finish output, ...)
65//!         -> implement engine::TranscodeDecodeHooks<C>
66//!            / engine::TranscodeEncodeHooks<C>
67//!            and use engine::TranscodeDecodeEngine<C, H>
68//!            / engine::TranscodeEncodeEngine<C, H>
69//! ```
70//!
71//! Unit-to-unit conversions, such as UTF-8 bytes to UTF-16 units, compose a
72//! decode side and an encode side. Use [`CodecTranscodeConverter`] for a strict
73//! pipeline and [`engine::TranscodeConvertEngine`] when either side needs
74//! policy hooks.
75//!
76//! # Layer Overview
77//!
78//! ```text
79//! concrete I/O crates
80//!   |
81//! TranscodeDecodeInput / TranscodeEncodeOutput  [feature = "io"]
82//!   |
83//! Transcode*Engine + Transcode*Hooks
84//! CodecTranscodeDecoder / Encoder / Converter
85//!   |
86//! Transcoder + TranscodeProgress + TranscodeStatus
87//! ValueEncoder / ValueDecoder
88//!   |
89//! Codec
90//! ```
91//!
92//! Implementing further up the stack does not require rewriting the lower
93//! layers. The adapter types turn any suitable [`Codec`] into owned-value or
94//! streaming APIs. Drop down to the engine and hook layer when the codec needs
95//! continuous-stream semantics or policy decisions.
96
97#![deny(missing_docs)]
98#![deny(unsafe_op_in_unsafe_fn)]
99
100mod byte_order;
101mod codec;
102mod nz;
103mod transcode;
104mod value;
105
106/// Policy-aware transcode engines, hooks, contexts, and policy actions.
107pub mod engine {
108    pub use crate::transcode::{
109        DecodeContext,
110        DecodeIncompleteAction,
111        DecodeIncompleteActionOf,
112        DecodeInvalidAction,
113        DecodeInvalidActionOf,
114        EncodeContext,
115        EncodeUnencodableAction,
116        EncodeUnencodableActionOf,
117        TranscodeConvertEngine,
118        TranscodeDecodeEngine,
119        TranscodeDecodeHooks,
120        TranscodeEncodeEngine,
121        TranscodeEncodeHooks,
122    };
123}
124
125pub use byte_order::{
126    BigEndian,
127    ByteOrder,
128    ByteOrderSpec,
129    LittleEndian,
130    NativeEndian,
131};
132pub use codec::{
133    Codec,
134    DecodeFailure,
135};
136pub use nz::{
137    nz,
138    nz_const,
139};
140#[cfg(feature = "io")]
141pub use transcode::{
142    AsyncTranscodeDecodeInput,
143    AsyncTranscodeDecodeStep,
144    AsyncTranscodeEncodeOutput,
145    TranscodeDecodeInput,
146    TranscodeEncodeOutput,
147};
148pub use transcode::{
149    CapacityError,
150    CodecTranscodeConverter,
151    CodecTranscodeDecoder,
152    CodecTranscodeEncoder,
153    TranscodeContractError,
154    TranscodeConvertError,
155    TranscodeConvertErrorOf,
156    TranscodeConverter,
157    TranscodeDecodeError,
158    TranscodeDecodeErrorOf,
159    TranscodeDecoder,
160    TranscodeDomainError,
161    TranscodeEncodeError,
162    TranscodeEncodeErrorOf,
163    TranscodeEncoder,
164    TranscodeFailure,
165    TranscodeProgress,
166    TranscodeStatus,
167    Transcoder,
168};
169pub use value::{
170    CodecValueDecoder,
171    CodecValueEncoder,
172    DecodeLifecycleOutput,
173    DecodeLifecycleProgress,
174    ValueDecoder,
175    ValueEncoder,
176};