binschema

    Safe, composable binary protocol codecs for MoonBit with CLI inspection and a Wasm visualizer

    binary
    codec
    parser
    wasm
    security
    Download zip
    Author
    Version
    0.3.0
    License
    Apache-2.0
    Last updated
    7 hours ago
    Downloads
    2

    Dependencies

    #BinSchema

    简体中文 · English · 🌐 在线 Playground

    用一份可组合的 Codec[T] 同时定义安全解码与编码,并让每个字节都可解释。

    BinSchema 是一个用 MoonBit 编写的安全二进制协议编解码框架。它将边界检查、资源限制、字段路径、偏移追踪和往返验证统一在同一套 API 中,并附带原生 CLI、Wasm-GC 浏览器检查器以及 ELF、PNG、WAVE、PCAP、ISO BMFF 与 DNS 六种真实格式实现。

    #特性

    • 安全默认值:64 MiB 核心输入/输出限制、集合长度上限、嵌套深度上限和严格 EOF 检查。
    • 双向定义:同一 Codec[T] 同时负责解码和编码,便于验证 encode(decode(bytes)) == bytes
    • 可诊断错误:错误包含分类、绝对字节偏移、字段路径和稳定的可读消息。
    • 结构追踪.named() 记录字段的 [start, end)、类型和值预览,可直接驱动可视化界面。
    • Schema 与静态检查:每个 Codec[T] 都能导出结构树,并通过 lint() 检查缺失的局部上限、动态分支和区域吞噬等协议风险。
    • 规范变长整数:内置安全的 uleb128()sleb128(),拒绝截断、溢出、超长和非最短编码。
    • 高级组合:提供 count_prefixeduntil_eoftagged,覆盖计数数组、流式尾读和标签联合。
    • 零拷贝解码decode_viewbytes_view_fixedremaining_viewchecksum_suffix_view 可直接借用 BytesView,有需要时再显式转成拥有型 Bytes
    • 缓冲式增量帧解析decode_prefixprobe_decodeIncrementalDecoder 支持分块输入、NeedMore 判定和多 frame 尾部保留;它是 buffered/retry framing,而不是 continuation-based parser。
    • 跨后端验证:Wasm、Wasm-GC、JavaScript、Native 四后端使用同一套测试。
    • 结构化安全回归:从真实格式的 Schema/Trace 派生确定性 mutation,覆盖截断、长度膨胀、CRC 损坏和字段边界翻转。
    • 真实格式校验:检查 PNG CRC 与块顺序、WAVE RIFF 结构、PCAP 字节序/长度/时间戳、ISO BMFF box 长度与扩展头,DNS section count、label 长度和压缩指针边界/方向/深度,以及 ELF32/64、端序、header table 范围、扩展 section numbering 与 section-name string table。

    #快速开始

    在 MoonBit 项目中添加依赖:

    moon add prowk/binschema

    并在调用方的 moon.pkg 中导入:

    import { "prowk/binschema" @bin, }

    内置真实格式位于独立包中;需要 PNG/WAVE/PCAP/BMFF/DNS/ELF 时再额外导入:

    import { "prowk/binschema/formats" @formats, }

    下面的快速开始同时是仓库里的可执行文档测试。组合一个带魔数、版本号和 LEB128 流 ID 的协议:

    ///|
    test "README quick start" {
    let packet = @binschema.pair(
    @binschema.magic(b"BS").named("magic"),
    @binschema.pair(
    @binschema.u8().named("version"),
    @binschema.uleb128().named("stream_id"),
    ),
    )
    let value = ((), (1U, 624485UL))
    let bytes = match @binschema.encode(packet, value) {
    Err(error) => fail(error.render())
    Ok(bytes) => bytes
    }
    match @binschema.decode(packet, bytes) {
    Err(error) => fail(error.render())
    Ok(decoded) => {
    assert_eq(decoded.value, value)
    assert_eq(decoded.trace.length(), 3)
    assert_true(packet.describe().contains("stream_id"))
    assert_eq(packet.lint().length(), 0)
    }
    }
    }

    基础 codec 覆盖有/无符号 8/16/32/64 位整数、大小端、ULEB128、SLEB128、固定字节串、magic、MSB 位域和布尔值。主要组合子包括 pairrepeatcount_prefixeduntil_eoftaggedxmapvalidateboundedlength_prefixedoptional_ifchecksum_suffix 与零拷贝 checksum_suffix_view。对于大输入,可用 decode_view + bytes_view_fixed / remaining_view 避免不必要的字节复制。

    #增量 / 流式输入

    对于 TCP、串口或其他分块输入,可以先用 probe_decode 判断当前缓冲区是否足够,或直接使用 IncrementalDecoder 累积 chunk。成功解析一个 frame 后,未消费尾部会保留给下一帧:

    ///|
    test "README incremental decode" {
    let codec = @binschema.pair(@binschema.u16_be(), @binschema.u8())
    let stream = @binschema.IncrementalDecoder::new(codec)
    assert_true(stream.feed(b"\x12") is @binschema.NeedMore)
    match stream.feed(b"\x34\x56\xaa") {
    @binschema.Done(decoded) => assert_eq(decoded.value, (0x1234U, 0x56U))
    _ => fail("expected one complete frame")
    }
    assert_eq(stream.buffered_bytes(), 1)
    }

    只有 UnexpectedEof 会被视为 NeedMore;校验失败、非法枚举值等错误会立即返回 FailedIncrementalDecoder 的通用实现会在 poll() 时从当前缓冲区起点重新尝试 codec,因此大量极小 chunk 场景应优先多次 append() 后再 poll(),减少重复解析。它不是保存解析 continuation 的真正状态机式 streaming parser。依赖当前区域结尾的 until_eof / remaining_* 应先放进协议定义的有界区域,再用于流式场景。

    #可复现的自定义协议示例

    仓库中的 examples/custom_packet 定义了如下布局:

    magic "BS" | version u8 | stream_id uleb128 | sequence u16_le

    克隆仓库后可直接运行:

    moon update moon run --target native examples/custom_packet

    预期输出包含:

    encoded: 42 53 01 e5 8e 26 07 00 stream_id: 624485 trace fields: 4

    如果想看一个更接近真实应用的完整协议示例,参见 examples/demo_protocol。它在一份 codec 树中组合 magic、版本校验、计数数组、tagged union、长度前缀 payload、字段 trace 和整包 checksum,展示“定义一次协议,同时获得编码、解码、校验与字节级解释”的完整工作流。

    运行:

    moon run --target native examples/demo_protocol

    #CLI

    moon run --target native cmd/main -- inspect image.png moon run --target native cmd/main -- inspect capture.pcap --json moon run --target native cmd/main -- verify audio.wav moon run --target native cmd/main -- sample png sample.png moon run --target native cmd/main -- sample bmff sample.mp4 moon run --target native cmd/main -- sample dns sample.dns moon run --target native cmd/main -- sample elf sample.elf moon run --target native cmd/main -- lint png moon run --target native cmd/main -- lint pcap --json moon run --target native cmd/main -- inspect sample.mp4 --format bmff moon run --target native cmd/main -- inspect sample.dns --format dns moon run --target native cmd/main -- inspect sample.elf moon run --target native cmd/main -- formats

    CLI 支持 ELF、PNG、WAVE、PCAP、BMFF 与 DNS;mp4 / isobmff 会解析为 BMFF。DNS 因缺少可靠固定 magic,不参与自动识别,需显式使用 --format dnslint <format> 会对内置协议声明的 Schema metadata 执行静态检查;Warning 仅提示风险,Lint Error 会返回数据错误退出码,便于接入 CI。对于自定义 Codec::make,linter 不会分析任意 decode/encode 闭包,也不能证明闭包与所声明 Schema 一致。输入上限为 64 MiB,并使用稳定退出码区分参数错误、数据错误和 I/O 错误。

    #真实格式支持边界

    formats 包首先是 BinSchema 架构的 reference implementations / stress cases,而不是六套完整领域库。当前验证重点如下:

    • PNG:signature、chunk 结构/顺序、CRC、核心 IHDR 合法性;不宣称实现全部图像语义。
    • WAVE:RIFF 长度、chunk/padding、fmt / data 基础一致性;不解码音频 payload。
    • PCAP:全局头、端序、packet 长度、时间戳范围和 snapshot 约束。
    • ISO BMFF:box header、32/64-bit size、size=0uuid 与未知 payload 保留;不解析完整媒体语义。
    • DNS:header/question/RR framing 与安全 compression pointer;RDATA 目前保持 raw bytes。
    • ELF:ELF32/64 header、端序、program/section table 范围、扩展 section numbering 和 section names;不解析 symbols、relocations、DWARF 或动态链接语义。

    因此 CLI 的 verify 表示“在 BinSchema 当前支持的结构规则下可解析且 decode→encode 字节一致”,不等价于对应标准的完整合规认证

    #Web / Wasm-GC 检查器

    无需安装 MoonBit,直接在浏览器中选择 ELF、PNG、WAVE、PCAP、常见 MP4 / ISO BMFF 或 DNS 文件即可查看结构;文件只在本地浏览器处理,不会上传。

    本地开发时,Wasm 二进制由源码构建生成,仓库不再提交 web/binschema.wasm

    moon build --target wasm-gc web/bridge --release cp _build/wasm-gc/release/build/web/bridge/bridge.wasm web/binschema.wasm python -m http.server 4173 --directory web

    Windows PowerShell 可用:

    Copy-Item _build/wasm-gc/release/build/web/bridge/bridge.wasm web/binschema.wasm

    打开 http://127.0.0.1:4173/。文件仅在浏览器本地处理,不会上传;浏览器输入上限为 16 MiB。界面可查看字段结构、十六进制范围和往返校验结果,并支持键盘导航。

    #仓库结构

    ├─ codec.mbt / decoder.mbt / encoder.mbt # 安全组合子核心 ├─ schema.mbt / lint.mbt # Schema 元数据与静态检查 ├─ primitives.mbt / varint.mbt # 定长与变长基础类型 ├─ formats/ # ELF / PNG / WAVE / PCAP / ISO BMFF / DNS ├─ cmd/main/ # 原生 CLI ├─ web/ # Wasm-GC 桥接与浏览器检查器 ├─ examples/custom_packet/ # 最小自定义协议示例 ├─ examples/demo_protocol/ # 更完整的真实协议示例 └─ docs/ # 架构和安全模型

    #开发与验收

    moon update moon info moon fmt --check moon check --target all --deny-warn moon test --target all --deny-warn moon test README.mbt.md --target native --deny-warn moon bench --build-only --target native --deny-warn moon test --target native --enable-coverage --deny-warn moon coverage analyze moon build --target native cmd/main --release moon build --target native examples/custom_packet --release moon build --target native examples/demo_protocol --release moon build --target wasm-gc web/bridge --release cmp README.md README.mbt.md

    测试覆盖整数边界、大小端、位对齐、资源限制、嵌套深度、组合子错误传播、变长整数异常、确定性 property roundtrip、固定二进制 corpus、基于 Schema/Trace 的结构化 mutation、损坏格式样例、CLI 调度和 Wasm JSON 契约。GitHub Actions 会在四后端执行这些测试,并验证示例构建、覆盖率流程和 README 同步。

    更多设计细节见 架构说明安全模型兼容性策略发布流程。安全问题请按 安全策略 中的方式报告。

    #License

    BinError

    pub struct BinError {
    kind : ErrorKind
    offset : Int
    path : String
    message : String
    } derive(Eq, ToJson,
    Debug
    )

    带绝对偏移和字段路径的错误。

    BinError::equal

    fn BinError::equal(BinError, BinError) -> Bool

    BinError::new

    fn BinError::new(kind : ErrorKind, offset : Int, path : String, message : String) -> BinError

    BinError::not_equal

    fn BinError::not_equal(x : BinError, y : BinError) -> Bool

    BinError::render

    fn BinError::render(self : BinError) -> String

    生成适合 CLI 和日志输出的稳定错误文本。

    BinError::to_json

    fn BinError::to_json(BinError) -> Json

    BinError::to_repr

    Codec

    pub struct Codec[T] {
    decode_impl : (Decoder) -> Result[T, BinError]
    encode_impl : (Encoder, T) -> Result[Unit, BinError]
    kind : String
    render : (T) -> String
    schema : SchemaNode
    }

    一份 Codec 同时定义解码和编码行为。

    Codec::decode_from

    fn[T] Codec::decode_from(self : Codec[T], decoder : Decoder) -> Result[T, BinError]

    Codec::describe

    fn[T] Codec::describe(self : Codec[T]) -> String

    渲染当前 Codec 的 Schema 树。

    Codec::encode_into

    fn[T] Codec::encode_into(self : Codec[T], encoder : Encoder, value : T) -> Result[Unit, BinError]

    Codec::lint

    fn[T] Codec::lint(self : Codec[T]) -> Array[LintIssue]

    直接检查 Codec 自带的 Schema 元数据。

    Codec::make

    fn[T] Codec::make(decode_impl : (Decoder) -> Result[T, BinError], encode_impl : (Encoder, T) -> Result[Unit, BinError], kind~ : String, render~ : (T) -> String, schema? : SchemaNode) -> Codec[T]

    Codec::named

    fn[T] Codec::named(self : Codec[T], name : String) -> Codec[T]

    为字段增加稳定路径和字节范围追踪。

    Codec::schema_node

    fn[T] Codec::schema_node(self : Codec[T]) -> SchemaNode

    返回当前 Codec 的独立 Schema 快照。

    Codec::validate

    fn[T] Codec::validate(self : Codec[T], predicate : (T) -> Bool, message : String) -> Codec[T]

    为 Codec 增加语义约束。

    Codec::xmap

    fn[A, B] Codec::xmap(self : Codec[A], decode_map : (A) -> Result[B, String], encode_map : (B) -> Result[A, String], render~ : (B) -> String) -> Codec[B]

    在不改变底层字节布局的前提下映射类型。

    DecodeOptions

    pub(all) struct DecodeOptions {
    limits : Limits
    require_eof : Bool
    } derive(Eq,
    Debug
    )

    DecodeOptions::default

    fn DecodeOptions::default() -> DecodeOptions

    DecodeOptions::equal

    DecodeOptions::not_equal

    fn DecodeOptions::not_equal(x : DecodeOptions, y : DecodeOptions) -> Bool

    DecodeStep

    pub(all) enum DecodeStep[T] {
    Done(Decoded[T])
    NeedMore
    Failed(BinError)
    }

    增量解码的单步结果。

    Decoded

    pub struct Decoded[T] {
    value : T
    consumed : Int
    trace : Array[TraceEntry]
    } derive(
    Debug
    )

    解码成功后的值、消费字节数和字段轨迹。

    Decoder

    pub struct Decoder {
    input : BytesView
    base_offset : Int
    offset : Int
    bit_offset : Int
    field_path : String
    depth : Int
    limits : Limits
    trace_entries : Array[TraceEntry]
    }

    有界二进制读取器。内部持有 BytesView,子区域解析不会复制底层字节。

    Decoder::absolute_offset

    fn Decoder::absolute_offset(self : Decoder) -> Int

    Decoder::align_byte

    fn Decoder::align_byte(self : Decoder) -> Unit

    Decoder::depth

    fn Decoder::depth(self : Decoder) -> Int

    Decoder::max_collection_length

    fn Decoder::max_collection_length(self : Decoder) -> Int

    Decoder::max_depth

    fn Decoder::max_depth(self : Decoder) -> Int

    Decoder::new

    fn Decoder::new(input : Bytes, limits : Limits) -> Decoder

    Decoder::new_view

    fn Decoder::new_view(input : BytesView, limits : Limits) -> Decoder

    从借用视图创建 Decoder,适合解析大缓冲区中的子区间而不复制。

    Decoder::offset

    fn Decoder::offset(self : Decoder) -> Int

    Decoder::path

    fn Decoder::path(self : Decoder) -> String

    Decoder::read_bits_msb

    fn Decoder::read_bits_msb(self : Decoder, width : Int) -> Result[UInt, BinError]

    Decoder::read_byte

    fn Decoder::read_byte(self : Decoder) -> Result[Byte, BinError]

    读取单个字节,避免为整数/变长整数解析创建临时字节串。

    Decoder::read_uint

    fn Decoder::read_uint(self : Decoder, width : Int, endian : Endian) -> Result[UInt, BinError]

    Decoder::read_uint64

    fn Decoder::read_uint64(self : Decoder, endian : Endian) -> Result[UInt64, BinError]

    Decoder::remaining

    fn Decoder::remaining(self : Decoder) -> Int

    Decoder::take_bytes

    fn Decoder::take_bytes(self : Decoder, count : Int) -> Result[Bytes, BinError]

    读取拥有所有权的字节串。需要零拷贝时优先使用 take_view

    Decoder::take_view

    fn Decoder::take_view(self : Decoder, count : Int) -> Result[BytesView, BinError]

    借用接下来 count 个字节,不复制底层缓冲区。

    Decoder::total_length

    fn Decoder::total_length(self : Decoder) -> Int

    Decoder::trace

    fn Decoder::trace(self : Decoder) -> Array[TraceEntry]

    Decoder::view_at

    fn Decoder::view_at(self : Decoder, offset : Int, count : Int) -> Result[BytesView, BinError]

    借用当前 Decoder 区域内任意绝对相对偏移的字节,不移动游标。 offset 相对于当前 Decoder 区域起点,而不是当前 cursor。

    EncodeOptions

    pub(all) struct EncodeOptions {
    limits : Limits
    } derive(Eq,
    Debug
    )

    EncodeOptions::default

    fn EncodeOptions::default() -> EncodeOptions

    EncodeOptions::equal

    EncodeOptions::not_equal

    fn EncodeOptions::not_equal(x : EncodeOptions, y : EncodeOptions) -> Bool

    Encoder

    pub struct Encoder {
    buffer :
    Buffer

    bit_buffer : UInt
    bit_count : Int
    field_path : String
    limits : Limits
    }

    与 Decoder 对称的有界二进制写入器。

    Encoder::align_byte

    fn Encoder::align_byte(self : Encoder, fill_bit? : Bool) -> Result[Unit, BinError]

    Encoder::finish

    fn Encoder::finish(self : Encoder) -> Result[Bytes, BinError]

    Encoder::length

    fn Encoder::length(self : Encoder) -> Int

    Encoder::max_collection_length

    fn Encoder::max_collection_length(self : Encoder) -> Int

    Encoder::new

    fn Encoder::new(limits : Limits) -> Encoder

    Encoder::path

    fn Encoder::path(self : Encoder) -> String

    Encoder::write_bits_msb

    fn Encoder::write_bits_msb(self : Encoder, value : UInt, width : Int) -> Result[Unit, BinError]

    Encoder::write_bytes

    fn Encoder::write_bytes(self : Encoder, bytes : BytesView) -> Result[Unit, BinError]

    Encoder::write_uint

    fn Encoder::write_uint(self : Encoder, value : UInt, width : Int, endian : Endian) -> Result[Unit, BinError]

    Encoder::write_uint64

    fn Encoder::write_uint64(self : Encoder, value : UInt64, endian : Endian) -> Result[Unit, BinError]

    Endian

    pub(all) enum Endian {
    Big
    Little
    } derive(Eq, ToJson,
    Debug
    )

    二进制整数的字节序。

    Endian::equal

    fn Endian::equal(Endian, Endian) -> Bool

    Endian::not_equal

    fn Endian::not_equal(x : Endian, y : Endian) -> Bool

    Endian::to_json

    fn Endian::to_json(Endian) -> Json

    Endian::to_repr

    ErrorKind

    pub(all) enum ErrorKind {
    UnexpectedEof
    Misaligned
    InvalidValue
    LimitExceeded
    ChecksumMismatch
    TrailingBytes
    Unsupported
    } derive(Eq, ToJson,
    Debug
    )

    统一的编解码错误分类。

    ErrorKind::equal

    fn ErrorKind::equal(ErrorKind, ErrorKind) -> Bool

    ErrorKind::name

    fn ErrorKind::name(self : ErrorKind) -> String

    ErrorKind::not_equal

    fn ErrorKind::not_equal(x : ErrorKind, y : ErrorKind) -> Bool

    ErrorKind::to_json

    fn ErrorKind::to_json(ErrorKind) -> Json

    IncrementalDecoder

    pub struct IncrementalDecoder[T] {
    codec : Codec[T]
    limits : Limits
    buffer : Array[Byte]
    }

    可持续喂入字节块的帧解码器。成功解析一个值后,仅移除已消费前缀并保留尾部数据。

    IncrementalDecoder::append

    fn[T] IncrementalDecoder::append(self : IncrementalDecoder[T], chunk : Bytes) -> Result[Unit, BinError]

    仅追加字节,不立即重新解析。大量小 chunk 场景可先批量 append,再 poll, 避免每个 chunk 都从缓冲区起点重试通用 codec。

    IncrementalDecoder::buffered_bytes

    fn[T] IncrementalDecoder::buffered_bytes(self : IncrementalDecoder[T]) -> Int

    当前仍未消费的缓冲字节数。

    IncrementalDecoder::clear

    fn[T] IncrementalDecoder::clear(self : IncrementalDecoder[T]) -> Unit

    丢弃当前尚未消费的数据。

    IncrementalDecoder::feed

    fn[T] IncrementalDecoder::feed(self : IncrementalDecoder[T], chunk : Bytes) -> DecodeStep[T]

    追加一个 chunk,并尝试解析一个 frame。

    IncrementalDecoder::new

    fn[T] IncrementalDecoder::new(codec : Codec[T], limits? : Limits) -> IncrementalDecoder[T]

    IncrementalDecoder::poll

    fn[T] IncrementalDecoder::poll(self : IncrementalDecoder[T]) -> DecodeStep[T]

    在不追加新数据的情况下尝试解析一个 frame。 通用 codec 会从当前缓冲区起点重新尝试,因此这属于 buffered/retry framing, 不是 continuation-based parser。

    Limits

    pub struct Limits {
    max_input_bytes : Int
    max_collection_length : Int
    max_depth : Int
    max_output_bytes : Int
    max_trace_entries : Int
    } derive(Eq,
    Debug
    )

    防止恶意长度字段造成过量内存或递归消耗。

    Limits::default

    fn Limits::default() -> Limits

    Limits::equal

    fn Limits::equal(Limits, Limits) -> Bool

    Limits::new

    fn Limits::new(max_input_bytes? : Int, max_collection_length? : Int, max_depth? : Int, max_output_bytes? : Int, max_trace_entries? : Int) -> Limits

    Limits::not_equal

    fn Limits::not_equal(x : Limits, y : Limits) -> Bool

    Limits::to_repr

    LintIssue

    pub(all) struct LintIssue {
    code : String
    severity : LintSeverity
    path : String
    message : String
    } derive(Eq, ToJson,
    Debug
    )

    Schema linter 产生的稳定、机器可读问题。

    LintIssue::equal

    fn LintIssue::equal(LintIssue, LintIssue) -> Bool

    LintIssue::not_equal

    fn LintIssue::not_equal(x : LintIssue, y : LintIssue) -> Bool

    LintIssue::render

    fn LintIssue::render(self : LintIssue) -> String

    LintIssue::to_json

    fn LintIssue::to_json(LintIssue) -> Json

    LintSeverity

    pub(all) enum LintSeverity {
    LintWarning
    LintError
    } derive(Eq, ToJson,
    Debug
    )

    Schema lint 的问题级别。Error 表示 Schema 元数据缺少关键安全约束, Warning 表示协议形状可工作,但会降低静态分析能力或扩大误用风险。

    LintSeverity::equal

    LintSeverity::name

    fn LintSeverity::name(self : LintSeverity) -> String

    LintSeverity::not_equal

    fn LintSeverity::not_equal(x : LintSeverity, y : LintSeverity) -> Bool

    LintSeverity::to_json

    SchemaNode

    pub(all) struct SchemaNode {
    name : String
    kind : String
    constraints : Array[String]
    children : Array[SchemaNode]
    } derive(Eq, ToJson,
    Debug
    )

    Codec 的可检查结构描述。它不参与编解码,只描述协议形状、名称与约束。

    SchemaNode::copy

    fn SchemaNode::copy(self : SchemaNode) -> SchemaNode

    SchemaNode::equal

    fn SchemaNode::equal(SchemaNode, SchemaNode) -> Bool

    SchemaNode::leaf

    fn SchemaNode::leaf(kind : String) -> SchemaNode

    SchemaNode::node

    fn SchemaNode::node(kind : String, children : Array[SchemaNode], constraints? : Array[String]) -> SchemaNode

    SchemaNode::not_equal

    fn SchemaNode::not_equal(x : SchemaNode, y : SchemaNode) -> Bool

    SchemaNode::render

    fn SchemaNode::render(self : SchemaNode) -> String

    将 Schema 树渲染成稳定、适合 CLI/文档展示的文本。

    SchemaNode::to_json

    fn SchemaNode::to_json(SchemaNode) -> Json

    SchemaNode::with_constraint

    fn SchemaNode::with_constraint(self : SchemaNode, constraint : String) -> SchemaNode

    SchemaNode::with_name

    fn SchemaNode::with_name(self : SchemaNode, name : String) -> SchemaNode

    TraceEntry

    pub struct TraceEntry {
    path : String
    kind : String
    start : Int
    end : Int
    value : String
    } derive(Eq, ToJson,
    Debug
    )

    字段的解析轨迹,可用于 CLI 和浏览器可视化。

    TraceEntry::equal

    fn TraceEntry::equal(TraceEntry, TraceEntry) -> Bool

    TraceEntry::not_equal

    fn TraceEntry::not_equal(x : TraceEntry, y : TraceEntry) -> Bool

    TraceEntry::to_json

    fn TraceEntry::to_json(TraceEntry) -> Json

    VERSION

    let VERSION : String

    BinSchema 的版本号。

    align

    fn align(boundary : Int) -> Codec[Unit]

    使用零填充将当前位置推进到给定字节边界;边界相对于当前解码区域起点。

    bits_msb

    fn bits_msb(width : Int) -> Codec[UInt]

    bool8

    fn bool8() -> Codec[Bool]

    bounded

    fn[T] bounded(length : Int, body : Codec[T], require_eof? : Bool) -> Codec[T]

    将一个 Codec 限制在固定长度的子区域中。

    bytes_fixed

    fn bytes_fixed(count : Int) -> Codec[Bytes]

    bytes_to_hex

    fn bytes_to_hex(bytes : Bytes) -> String

    bytes_to_hex_preview

    fn bytes_to_hex_preview(bytes : Bytes, max_bytes : Int) -> String

    为检查轨迹生成有界十六进制预览,避免大字段制造巨量日志。

    bytes_view_fixed

    fn bytes_view_fixed(count : Int) -> Codec[BytesView]

    零拷贝固定长度字节字段。返回的 BytesView 借用原始输入。

    bytes_view_to_hex_preview

    fn bytes_view_to_hex_preview(bytes : BytesView, max_bytes : Int) -> String

    BytesView 版本的有界十六进制预览;不会复制整个输入。

    checksum_suffix

    fn[T] checksum_suffix(body : Codec[T], checksum_codec : Codec[UInt], calculate : (Bytes) -> UInt) -> Codec[T]

    兼容原有拥有型校验和回调。新代码优先使用 checksum_suffix_view 避免解码时复制。

    checksum_suffix_view

    fn[T] checksum_suffix_view(body : Codec[T], checksum_codec : Codec[UInt], calculate : (BytesView) -> UInt) -> Codec[T]

    为任意字节对齐的主体增加尾随校验值。

    count_prefixed

    fn[T] count_prefixed(count_codec : Codec[UInt], item : Codec[T], max_count? : Int) -> Codec[Array[T]]

    使用前置计数字段编解码数组。

    decode

    fn[T] decode(codec : Codec[T], input : Bytes) -> Result[Decoded[T], BinError]

    使用安全默认限制解码完整输入。

    decode_prefix

    fn[T] decode_prefix(codec : Codec[T], input : Bytes) -> Result[Decoded[T], BinError]

    解码一个前缀值,不要求消费完整输入。适合一块缓冲区中串联多个 frame。

    decode_prefix_view

    fn[T] decode_prefix_view(codec : Codec[T], input : BytesView) -> Result[Decoded[T], BinError]

    前缀解码的零拷贝视图版本。

    decode_prefix_view_with_options

    fn[T] decode_prefix_view_with_options(codec : Codec[T], input : BytesView, options : DecodeOptions) -> Result[Decoded[T], BinError]

    使用自定义限制进行零拷贝前缀解码。

    decode_prefix_with_options

    fn[T] decode_prefix_with_options(codec : Codec[T], input : Bytes, options : DecodeOptions) -> Result[Decoded[T], BinError]

    decode_prefix 的自定义限制版本。

    decode_view

    fn[T] decode_view(codec : Codec[T], input : BytesView) -> Result[Decoded[T], BinError]

    从借用字节视图解码,允许返回引用原始输入的 BytesView

    decode_view_with_options

    fn[T] decode_view_with_options(codec : Codec[T], input : BytesView, options : DecodeOptions) -> Result[Decoded[T], BinError]

    decode_with_options 的零拷贝视图版本。

    decode_with_options

    fn[T] decode_with_options(codec : Codec[T], input : Bytes, options : DecodeOptions) -> Result[Decoded[T], BinError]

    使用自定义限制解码完整输入。

    encode

    fn[T] encode(codec : Codec[T], value : T) -> Result[Bytes, BinError]

    将值编码成不可变字节串。

    encode_with_options

    fn[T] encode_with_options(codec : Codec[T], value : T, options : EncodeOptions) -> Result[Bytes, BinError]

    使用自定义限制编码值。

    i16_be

    fn i16_be() -> Codec[Int]

    i16_le

    fn i16_le() -> Codec[Int]

    i32_be

    fn i32_be() -> Codec[Int]

    i32_le

    fn i32_le() -> Codec[Int]

    i64_be

    fn i64_be() -> Codec[Int64]

    i64_le

    fn i64_le() -> Codec[Int64]

    fn i8() -> Codec[Int]

    length_prefixed

    fn[T] length_prefixed(length_codec : Codec[UInt], body : Codec[T], max_length? : Int) -> Codec[T]

    使用无符号长度字段限定后续值。

    lint_schema

    fn lint_schema(schema : SchemaNode) -> Array[LintIssue]

    对任意 SchemaNode 执行确定性的静态检查。

    magic

    fn magic(expected : Bytes) -> Codec[Unit]

    nul_terminated_bytes

    fn nul_terminated_bytes(max_length? : Int) -> Codec[Bytes]

    读取以 NUL 结尾的字节串;返回值不包含终止字节。

    optional_if

    fn[T] optional_if(flag : Codec[Bool], item : Codec[T]) -> Codec[T?]

    编解码带显式存在标记的可选字段。

    padding

    fn padding(count : Int) -> Codec[Unit]

    消费或写入固定数量的零填充字节。

    pair

    fn[A, B] pair(first : Codec[A], second : Codec[B]) -> Codec[(A, B)]

    顺序组合两个 Codec。

    probe_decode

    fn[T] probe_decode(codec : Codec[T], input : Bytes) -> DecodeStep[T]

    将 UnexpectedEof 解释为“需要更多数据”,其余错误保持为 Failed。

    probe_decode_with_options

    fn[T] probe_decode_with_options(codec : Codec[T], input : Bytes, options : DecodeOptions) -> DecodeStep[T]

    probe_decode 的自定义限制版本。

    remaining_bytes

    fn remaining_bytes() -> Codec[Bytes]

    拥有型版本的“消费全部剩余字节”组合子。

    remaining_view

    fn remaining_view() -> Codec[BytesView]

    零拷贝消费当前区域的全部剩余字节。

    repeat

    fn[T] repeat(count : Int, item : Codec[T]) -> Codec[Array[T]]

    按固定数量重复元素 Codec。

    sleb128

    fn sleb128() -> Codec[Int64]

    64 位有符号 LEB128。解码严格要求最短规范表示,最多消费 10 字节。

    tagged

    fn[T] tagged(tag_codec : Codec[UInt], select : (UInt) -> Result[Codec[T], String], tag_of : (T) -> Result[UInt, String], render~ : (T) -> String) -> Codec[T]

    由标签值动态选择后续 Codec,适合 tagged union / switch 协议。

    u16_be

    fn u16_be() -> Codec[UInt]

    u16_le

    fn u16_le() -> Codec[UInt]

    u32_be

    fn u32_be() -> Codec[UInt]

    u32_le

    fn u32_le() -> Codec[UInt]

    u64_be

    fn u64_be() -> Codec[UInt64]

    u64_le

    fn u64_le() -> Codec[UInt64]

    fn u8() -> Codec[UInt]

    uleb128

    fn uleb128() -> Codec[UInt64]

    64 位无符号 LEB128。解码严格要求最短规范表示,最多消费 10 字节。

    until_eof

    fn[T] until_eof(item : Codec[T]) -> Codec[Array[T]]

    重复解码元素直到当前输入区域耗尽。每个元素必须至少消费一个字节。