qubit-codec-binary 0.1.0

Buffer-oriented binary codecs for Rust
Documentation
# Qubit Binary Codec 用户指南

`qubit-codec-binary` 提供缓冲区级 binary codec,适合 parser、二进制格式和
已经自行管理 buffer 的 stream adapter。

## 层次

- 使用 `BinaryCodec<T, O>` 处理明确位宽的 primitive integer 和浮点数。
- 使用 `Leb128Codec<T, P>` 处理 unsigned / signed LEB128 值。
- 当有符号值通常接近零、包括负数也要保持紧凑时,使用 `ZigZagCodec<T, P>`- 使用 `Strict` 拒绝非 canonical LEB128 payload,使用 `NonStrict` 做宽松解码。

本库只重导出属于 binary codec 表面的必要 `qubit-codec` 原语:`Codec`、
`ByteOrder`、`ByteOrderSpec`、`BigEndian` 和 `LittleEndian`。同时暴露 sealed
`Leb128DecodePolicy` trait,用于内置 LEB128 policy marker。通用 adapter、
engine、hook 和 value trait 请直接从 `qubit-codec` 引入。

## Fixed-Width 值

`BinaryCodec` 支持 `u8`、`i8`、`u16`、`i16`、`u32`、`i32`、`u64`、`i64`、
`u128`、`i128`、`f32` 和 `f64`。它不实现 `usize` 或 `isize`,因为它们的
字节宽度依赖目标平台。

```rust
use qubit_codec_binary::{
    BigEndian,
    BinaryCodec,
};

let mut output = [0_u8; BinaryCodec::<u32, BigEndian>::MAX_UNITS_PER_VALUE];
unsafe {
    BinaryCodec::<u32, BigEndian>::encode_unchecked(0x0102_0304, &mut output, 0);
}
assert_eq!([1, 2, 3, 4], output);
```

这些 unchecked API 面向调用方已经验证过 buffer 容量的热路径。

## LEB128 与 ZigZag

```rust
use qubit_codec_binary::{
    Leb128Codec,
    NonStrict,
    ZigZagCodec,
};

let mut unsigned = [0_u8; Leb128Codec::<u64, NonStrict>::MAX_UNITS_PER_VALUE];
let written = unsafe { Leb128Codec::<u64, NonStrict>::encode_unchecked(300, &mut unsigned, 0) };
assert_eq!(2, written);

let mut signed = [0_u8; ZigZagCodec::<i64, NonStrict>::MAX_UNITS_PER_VALUE];
let written = unsafe { ZigZagCodec::<i64, NonStrict>::encode_unchecked(-42, &mut signed, 0) };
assert_eq!(1, written);
```

`MIN_UNITS_PER_VALUE` 适合用于判断是否可以开始解码。
`MAX_UNITS_PER_VALUE` 是容量上界,适合用于分配输出 buffer,或者在调用方无法
证明终止字节位置时保证最大可读范围。

## LEB128 解码错误

`Leb128DecodeError` 区分当前值的起点和错误被发现的位置:

- `start_index()` 返回当前尝试解码的值从哪个字节开始。
- `error_index()` 返回解码发现错误的位置。对于 incomplete input,它是当前可用
  输入之后、下一字节应出现的边界。
- `required()``available()``additional()` 描述 incomplete input。
- `consumed()` 描述 malformed 或 non-canonical input 后调用方可以消费多少
  无效字节。

## Unsafe 边界

这些 codec 是低层构件。unchecked 方法不负责发现 buffer 空间是否足够:

- Fixed-width `BinaryCodec` 的 decode 和 encode 调用要求从给定 index 开始有
  `MIN_UNITS_PER_VALUE` 个可读字节或 `MAX_UNITS_PER_VALUE` 个可写字节。
  对于 fixed-width 值,这两个边界相等。
- LEB128 和 ZigZag 的 encode 调用要求从给定 index 开始有
  `MAX_UNITS_PER_VALUE` 个可写字节。
- LEB128 和 ZigZag 的 decode 调用要求从给定 index 开始至少有
  `MIN_UNITS_PER_VALUE` 个可读字节。调用方通常应尽量提供到
  `MAX_UNITS_PER_VALUE`,除非 EOF 已经无法继续读取。
- 如果 EOF 导致调用方无法提供足够字节来完成一个变长值,上层应把该值作为
  `Leb128DecodeError` 中的不完整值处理。

对外暴露安全 API 时,应先验证这些条件,再跨过 unsafe 边界。

## 安全 Adapter 与 Stream

本 crate 刻意停留在 buffer-level binary codec 层。owned single-value adapter、
通用 buffered engine 或 conversion trait 请直接从 `qubit-codec` 引入,并把这些
binary codec 作为低层 codec 实现使用。

如果自行封装 `decode_unchecked`,调用 unsafe 方法前要先检查起始 index 后至少有
`MIN_UNITS_PER_VALUE` 个可读字节。对于 single-value decoder,还需要由你的格式决定
返回的 `consumed` 之后是否允许 trailing bytes。

如果需要围绕这些 codec 的 `std::io::Read` / `Write` adapter,请使用
`qubit-io-binary`。