Skip to main content

moqtap_codec/draft21/
mod.rs

1//! MoQT wire codec for draft-21.
2//!
3//! **Draft-21 is draft-20 restructured, and nothing a decoder can observe
4//! changed.** Every message keeps its code point, every field its width and
5//! its place, every registry its rows. The one wire-visible consequence is the
6//! ALPN, which the draft derives from its own number: `moqt-21`.
7//!
8//! What did change is where the rules are written down. Two hundred numbered
9//! sections became two hundred and fourteen and only eleven keep both their
10//! title and their number, so **every section, table and figure reference in
11//! this module is draft-21's own**. A draft-20 number carried over would
12//! mostly still resolve — to a section that exists and states something else.
13//!
14//! Two normative sentences were reworded on the way, so *a restructure moves
15//! text without touching it* is very nearly true and not quite. The
16//! AUTHORIZATION TOKEN repetition rule takes a different subject here than it
17//! took in draft-20, and LOCATION_FILTER's definition lost the opening
18//! sentence that named its encoding — with the `Length` field still in the
19//! structure, so the wire is as it was. Neither changes what either requires,
20//! and both are quoted at the sites that read them.
21//!
22//! The rest of this list is what a reader coming from draft-19 needs; draft-20
23//! made these changes and draft-21 keeps every one of them.
24//!
25//! - **FETCH (0x16) is rewritten.** The `Fetch Type` field, the Standalone
26//!   Fetch and Joining Fetch structures and the Fetch Type registry are all
27//!   gone. Track Namespace and Track Name are inline fields of FETCH itself, in
28//!   the positions they occupied inside the old Standalone Fetch, and the range
29//!   travels in the `LOCATION_FILTER` message parameter. The codepoint did not
30//!   change, so a draft-19 decoder reads the Number of Track Namespace Fields
31//!   count as a Fetch Type and mis-parses in silence; there is no in-band
32//!   version signal to catch it (Section 9.11)
33//! - **PUBLISH_STATE_NOTIFY (0x22) is new.** A publisher-only, unilateral
34//!   report that a subscription's state changed for a reason other than a
35//!   subscriber-sent REQUEST_UPDATE. It has no Request ID field — the message
36//!   is identified by the bidirectional request stream it arrives on, like
37//!   SUBSCRIBE_OK, PUBLISH_DONE and FETCH_OK (Section 9.10)
38//! - **`LOCATION_FILTER` (0x21) is restructured.** The Filter Type enum
39//!   (draft-19's 0x1 Next Group Start / 0x2 Largest Object / 0x3 AbsoluteStart
40//!   / 0x4 AbsoluteRange) is gone; the filter's shape now comes from how many
41//!   `vi64` fields its value holds (Section 9.20.10)
42//! - **Ranges are inclusive at both ends**, on subscriptions and on fetches.
43//!   Draft-19's fetch end was "the last Object, plus 1; or 0 to indicate the
44//!   entire Group"; both conventions are deleted. This change is absent from
45//!   the draft's own change log, and a draft-19 encoder ported forward with its
46//!   end-location arithmetic intact fetches one object too many
47//!   (Sections 3.3.1, 9.11, 9.12)
48//! - **`FILL_PARAMETERS` (0x23) is new**: a length-prefixed parameter whose
49//!   value is a nested parameter block, and whose mere presence on a SUBSCRIBE
50//!   or a REQUEST_UPDATE asks the publisher to open a fill fetch stream
51//!   (Section 9.20.16)
52//! - **`INCLUDE_PROPERTIES` (0x35) is new**: a uint8 opt-out from Track
53//!   Properties on the responding OK, default 1 (Section 9.20.22)
54//! - Three code points are removed: `SUBSCRIPTION_ENDED` (PUBLISH_DONE 0x3),
55//!   `VERSION_NEGOTIATION_FAILED` (session 0x15) and
56//!   `INVALID_JOINING_REQUEST_ID` (REQUEST_ERROR 0x32). Two whole enumerations
57//!   go with them: the Fetch Type registry and the Location Filter Type enum
58//! - `PUBLISH_DONE.Stream Count`'s "unknown" sentinel moves from `2^62 - 1` to
59//!   `2^64 - 1`, and the count now includes fill fetch streams (Section 9.9)
60//! - Subscription parameters moved off `PUBLISH_OK`. Six parameter definitions
61//!   dropped it from their "MAY appear in" list and several gained `PUBLISH`;
62//!   `EXPIRES` (0x08) is the only one that still names it (Section 9.20)
63//! - The data-plane headers rename their leading field `Type` to `Type Flags`
64//!   and move the validity rules out of the figure into prose. The field list,
65//!   order, widths and the set of valid values are all unchanged; what changed
66//!   is the receive path. Sections 11.2.1 and 11.3.1 give **different** rule
67//!   sets — subgroup's reserved bit 4 must be 1, datagram's must be 0, and
68//!   subgroup has no "unspecified bit" clause because bits 0-6 are all
69//!   specified for it
70//! - A fetch stream gains a third End of Range marker, `End of Timed-Out
71//!   Range` (Serialization Flags `0x20C`), for the Objects a relay abandoned
72//!   when its `FILL_TIMEOUT` budget ran out. Draft-19 reported those as Unknown
73//!   gaps (Section 11.4.1, Table 7)
74//! - Draft-20 renumbered too, inserting PUBLISH_STATE_NOTIFY and shifting
75//!   everything after it; draft-21 renumbered again and far more widely. Both
76//!   are behind us: the numbers below are draft-21's
77//!
78//! # Where this codec had to choose
79//!
80//! Draft-21 leaves several wire questions open. Each decision is recorded at
81//! the encode or decode site that makes it, and each says that the draft does
82//! not state it. They are, with the site that carries the comment:
83//!
84//! - `FILL_PARAMETERS`'s value begins with a `Number of Parameters` count —
85//!   [`message::decode_fill_parameters`]
86//! - the `Type Delta` chain restarts inside `FILL_PARAMETERS` and the outer
87//!   chain is unaffected — [`message::decode_fill_parameters`]
88//! - a `LOCATION_FILTER`'s field count comes from parsing, never from the byte
89//!   length — [`message::decode_location_filter`]
90//! - a non-minimally encoded `Type Flags` is accepted on receive and never
91//!   emitted — [`data_stream::SubgroupHeader::decode`](crate::draft21::data_stream::SubgroupHeader::decode) and
92//!   [`data_stream::DatagramHeader::decode`](crate::draft21::data_stream::DatagramHeader::decode)
93//! - `PUBLISH_DONE.Stream Count`'s `2^64 - 1` sentinel is indistinguishable
94//!   from a well-formed exact count —
95//!   [`message::publish_done_codes::STREAM_COUNT_UNKNOWN`]
96//! - `PUBLISH_STATE_NOTIFY`'s parameter allow-list is treated as closed —
97//!   [`message::parameter_in_scope`]
98//! - `Object Payload Length` is present on an End-of-Range marker record,
99//!   encoded as 0, and the ordinary delta arithmetic applies to the marker's
100//!   two fields — [`data_stream::FetchObjectHeader`]
101
102#[allow(missing_docs)]
103pub mod data_stream;
104pub mod error_codes;
105/// This draft's field names for a decoded control message.
106pub mod fields;
107#[allow(missing_docs)]
108pub mod message;
109#[allow(missing_docs)]
110pub mod types;