moqtap-codec
Zero-dependency MoQT wire codec — draft-conforming parser and writer for every MoQT draft from draft-07 through draft-17.
What it does
Section titled “What it does”Pure encoding and decoding of MoQT protocol messages — no I/O, no async runtime, no network dependencies. It is the foundational building block that every other moqtap crate depends on.
- Every MoQT control message (setup, subscribe, publish, fetch, namespace, track status, goaway) per supported draft
- Data stream headers (subgroup, datagram, fetch, object)
- QUIC variable-length integer (varint) encoding per RFC 9000
- Key-value parameter (KVP) pairs
- Core protocol types:
TrackNamespace,Location,FilterType,GroupOrder,ObjectStatus - Session and request error codes, per-draft
- Runtime draft dispatch via the
dispatchmodule
Module layout
Section titled “Module layout”Each draft lives in its own module with an independent implementation; no wire-level code is shared across drafts. Shared primitives sit at the crate root.
moqtap_codec:: varint, kvp, types, version, error (shared) dispatch (runtime Any* enums) draft07, draft08, ..., draft17 (per-draft wire format)Draft selection
Section titled “Draft selection”Each draft is behind a Cargo feature. The default is all-drafts.
# every draft (default)moqtap-codec = "0.1"
# draft-14 onlymoqtap-codec = { version = "0.1", default-features = false, features = ["draft14"] }
# draft-07 plus draft-14 for runtime dispatchmoqtap-codec = { version = "0.1", default-features = false, features = ["draft07", "draft14"] }Available features: draft07, draft08, …, draft17, plus all-drafts.
Per-draft encoding and decoding
Section titled “Per-draft encoding and decoding”use moqtap_codec::draft14::message::{ControlMessage, ClientSetup};use moqtap_codec::varint::VarInt;
let msg = ControlMessage::ClientSetup(ClientSetup { supported_versions: vec![VarInt::from_u64(0xff00000e).unwrap()], parameters: vec![],});
let mut buf = Vec::new();msg.encode(&mut buf).unwrap();
let mut cursor = &buf[..];let decoded = ControlMessage::decode(&mut cursor).unwrap();assert_eq!(msg, decoded);Runtime dispatch across drafts
Section titled “Runtime dispatch across drafts”When you don’t know the draft at compile time (e.g., a proxy that observes any client), use the dispatch module. It exposes one Any* enum per message category, each with one variant per enabled draft feature:
AnyControlMessageAnySubgroupHeaderAnyFetchHeaderAnyDatagramHeaderAnyObjectHeader
use moqtap_codec::dispatch::AnyControlMessage;use moqtap_codec::version::DraftVersion;
let mut cursor: &[u8] = &wire_bytes;let msg = AnyControlMessage::decode(DraftVersion::Draft14, &mut cursor)?;match msg { AnyControlMessage::Draft14(inner) => { /* ... */ } _ => {}}Dependencies
Section titled “Dependencies”Zero runtime dependencies. The codec is pure byte manipulation — no tokio, no bytes, no serde.