Skip to main content

Module draft_table

Module draft_table 

Source
Expand description

One shape for a per-draft lookup, shared by the tables that need it.

Two functions in this crate answer the same kind of question — what does draft N call this number? — for two different registries: crate::message_names::message_type_name for control message type IDs and crate::setup_option_names::setup_option_name for setup parameters. Both have to take the draft as well as the codepoint, because the codepoints are reused and retired rather than reserved, and each one’s per-draft half lives in that draft’s own module. So both are the same one-arm-per-draft dispatch over crate::version::DraftVersion, and the interesting part is not the arms but what happens at the end of them.

§The arm that is not written here, and why it is the whole point

A match over crate::version::DraftVersion has to answer for every variant, and the obvious way to end one is _ => None. That reads as a draft this build did not compile has no name for anything, which is true and is not the whole of what it does: it also answers for a draft nobody has added yet. The day a Draft21 variant lands, a table that ends in a catch-all goes on compiling and starts answering “no name” for every draft-21 codepoint — which is indistinguishable from a correct answer about an unassigned number, and which nothing in the build says a word about.

That is the drift scripts/check-draft-parity.py rule 3 exists to catch: a match that answers for two or more drafts, reaches the newest, and then falls through to a _ arm that is not loud. by_draft answers it structurally rather than with a louder arm: spell both feature states for every draft and the match has no catch-all left to fall into, so a fifteenth variant stops this crate compiling instead of being answered quietly.

§What that trades away, stated rather than assumed

A macro invocation lists its drafts as bare identifiers — Draft07, not DraftVersion::Draft07 — so check-draft-parity.py does not recognise either table as a draft-enumerating construct, and rules 2 and 3 do not count them. That is a smaller census and a stronger guarantee: rule 2 asks whether a list reaches the newest draft, and here a list that does not is a non-exhaustive match, which is a compile error in fourteen feature configurations. A textual gate is what you need when the compiler cannot see the omission; it is not an improvement on the compiler seeing it.

The script’s own summary already excludes “anything a macro spells by token concatenation”, and both crate::setup_option_names and its sibling rely on exactly this, with the argument living in one place instead of being restated beside each table.

§Why the answer is not shared, only the shape

The two tables do not have the same signature and are not meant to. One takes a u64 and answers Option<&'static str>; the other takes a whole crate::kvp::KeyValuePair, because drafts 11 through 13 name a setup parameter from its key and the shape of its value, and answers Option<String> out of the draft’s own field renderer. Folding those into one function would mean inventing a common type that neither registry has.

So what is shared is the dispatch and nothing else: the draft lookup, the per-draft cfg pair, and the absent answer. Each table keeps its own signature, its own doctest and its own rationale for what its codepoints mean.

Macros§

by_draft 🔒
Answer a question per draft, with an arm for every draft and no catch-all.