qubit-codec 0.11.1

Core codec traits and buffer conversion primitives for Rust
Documentation
// =============================================================================
//    Copyright (c) 2026 Haixing Hu.
//
//    SPDX-License-Identifier: Apache-2.0
//
//    Licensed under the Apache License, Version 2.0.
// =============================================================================
//! # qubit-codec
//!
//! Domain-neutral codec traits and buffer conversion primitives.
//!
//! `qubit-codec` is the foundation shared by the Qubit binary, text, misc, and
//! I/O codec crates. It defines the small contracts that concrete format crates
//! build on, without shipping concrete binary or text formats itself.
//!
//! # Overview
//!
//! The crate provides:
//!
//! - [`Codec`] for low-level single-value codecs over caller-managed buffers.
//! - [`CodecValueEncoder`] and [`CodecValueDecoder`] for owned one-value
//!   convenience APIs.
//! - [`CodecTranscodeEncoder`], [`CodecTranscodeDecoder`], and
//!   [`CodecTranscodeConverter`] for strict streaming adapters around a
//!   [`Codec`].
//! - [`engine::TranscodeEncodeEngine`], [`engine::TranscodeDecodeEngine`], and
//!   [`engine::TranscodeConvertEngine`] for policy-aware buffered loops.
//! - [`engine::TranscodeEncodeHooks`] and [`engine::TranscodeDecodeHooks`] for
//!   replacement, skip, report, finish, and reset policy decisions.
//! - [`Transcoder`], [`TranscodeProgress`], and [`TranscodeStatus`] for
//!   caller-managed streaming conversion.
//! - [`ValueEncoder`] and [`ValueDecoder`] for whole-value convenience APIs.
//! - [`ByteOrder`], [`ByteOrderSpec`], [`BigEndian`], [`LittleEndian`], and
//!   [`NativeEndian`] for shared byte-order metadata.
//! - [`nz()`] and [`nz!`] for checked `NonZeroUsize` construction shared by
//!   codec implementations.
//!
//! Concrete codecs live in sibling crates such as `qubit-codec-binary`,
//! `qubit-codec-text`, and `qubit-codec-misc`.
//!
//! # Choosing an Abstraction
//!
//! Pick the smallest layer that matches the shape of the problem:
//!
//! ```text
//! What are you writing?
//!
//! +-- A codec for one logical value
//! |   (UTF-8 char, LEB128 integer, fixed-width scalar, ...)
//! |       -> implement Codec
//! |
//! +-- A whole-value codec where a single-value quantum is not useful
//! |   (Base64 text, percent encoding, escaped strings, ...)
//! |       -> implement ValueEncoder<Input> / ValueDecoder<Input>
//! |
//! +-- A strict streaming wrapper around an existing Codec
//! |       -> use CodecTranscodeDecoder<C> / CodecTranscodeEncoder<C>
//! |          / CodecTranscodeConverter<D, E>
//! |
//! +-- An owned-output wrapper around an existing Codec
//! |       -> use CodecValueEncoder<C> / CodecValueDecoder<C>
//! |
//! +-- A streaming codec with policy decisions
//!     (skip, replace, count, report, finish output, ...)
//!         -> implement engine::TranscodeDecodeHooks<C>
//!            / engine::TranscodeEncodeHooks<C>
//!            and use engine::TranscodeDecodeEngine<C, H>
//!            / engine::TranscodeEncodeEngine<C, H>
//! ```
//!
//! Unit-to-unit conversions, such as UTF-8 bytes to UTF-16 units, compose a
//! decode side and an encode side. Use [`CodecTranscodeConverter`] for a strict
//! pipeline and [`engine::TranscodeConvertEngine`] when either side needs
//! policy hooks.
//!
//! # Layer Overview
//!
//! ```text
//! concrete I/O crates
//!   |
//! TranscodeDecodeInput / TranscodeEncodeOutput  [feature = "io"]
//!   |
//! Transcode*Engine + Transcode*Hooks
//! CodecTranscodeDecoder / Encoder / Converter
//!   |
//! Transcoder + TranscodeProgress + TranscodeStatus
//! ValueEncoder / ValueDecoder
//!   |
//! Codec
//! ```
//!
//! Implementing further up the stack does not require rewriting the lower
//! layers. The adapter types turn any suitable [`Codec`] into owned-value or
//! streaming APIs. Drop down to the engine and hook layer when the codec needs
//! continuous-stream semantics or policy decisions.

#![deny(missing_docs)]
#![deny(unsafe_op_in_unsafe_fn)]

mod byte_order;
mod codec;
mod nz;
mod transcode;
mod value;

/// Policy-aware transcode engines, hooks, contexts, and policy actions.
pub mod engine {
    pub use crate::transcode::{
        DecodeContext,
        DecodeIncompleteAction,
        DecodeIncompleteActionOf,
        DecodeInvalidAction,
        DecodeInvalidActionOf,
        EncodeContext,
        EncodeUnencodableAction,
        EncodeUnencodableActionOf,
        TranscodeConvertEngine,
        TranscodeDecodeEngine,
        TranscodeDecodeHooks,
        TranscodeEncodeEngine,
        TranscodeEncodeHooks,
    };
}

pub use byte_order::{
    BigEndian,
    ByteOrder,
    ByteOrderSpec,
    LittleEndian,
    NativeEndian,
};
pub use codec::{
    Codec,
    DecodeFailure,
};
pub use nz::{
    nz,
    nz_const,
};
#[cfg(feature = "io")]
pub use transcode::{
    AsyncTranscodeDecodeInput,
    AsyncTranscodeDecodeStep,
    AsyncTranscodeEncodeOutput,
    TranscodeDecodeInput,
    TranscodeEncodeOutput,
};
pub use transcode::{
    CapacityError,
    CodecTranscodeConverter,
    CodecTranscodeDecoder,
    CodecTranscodeEncoder,
    TranscodeContractError,
    TranscodeConvertError,
    TranscodeConvertErrorOf,
    TranscodeConverter,
    TranscodeDecodeError,
    TranscodeDecodeErrorOf,
    TranscodeDecoder,
    TranscodeDomainError,
    TranscodeEncodeError,
    TranscodeEncodeErrorOf,
    TranscodeEncoder,
    TranscodeFailure,
    TranscodeProgress,
    TranscodeStatus,
    Transcoder,
};
pub use value::{
    CodecValueDecoder,
    CodecValueEncoder,
    DecodeLifecycleOutput,
    DecodeLifecycleProgress,
    ValueDecoder,
    ValueEncoder,
};