Skip to main content

kvp_entries

Function kvp_entries 

Source
pub(crate) fn kvp_entries<F>(params: &[KeyValuePair], render: F) -> FieldValue
where F: FnMut(u64, &KvpValue) -> (Option<&'static str>, Option<FieldValue>),
Expand description

Render a Key-Value-Pair list as entries, in the order the wire carried them.

§Why a list and not a map keyed by name

Every draft models a parameter block as an ordered list of (Type, Value), with types ascending. Rendering it as a map keyed by the draft’s name for each type reads better and loses three things:

  • Repeats. Two parameter definitions permit a message to carry their type more than once — AUTHORIZATION_TOKEN, and on drafts 19 and 20 the five Range Filters. A map has one slot per name, so two SUBGROUP_FILTERs under different SetIDs became the second one alone: the frame said “Subgroup 1-3 in set 0, or 10-12 in set 1” and the record said “10-12”, which is not a narrower reading of the request but a different one.
  • Order. Drafts 16 and later require that “Parameters MUST be serialized in ascending order by Type” and answer a descending pair with a session close. A map has no order, so no vector could state that rule at all.
  • Unknown types. A map has no name to key them under, so each draft invented something: 11 through 14 dropped them, and the later ones parked them in a second, differently-shaped unknown array beside the named ones. Two containers for one wire field.

An entry list has none of those problems and needs no special case for any of them: a repeat is two entries, order is the list’s, and an unknown type is an entry without a name.

§The entry

type is always present, as the lowercase hex of the Parameter Type. name is present when the draft names that type. Then exactly one of:

  • value — the decoded value, when this codec models it. A varint renders as its number, a structure as a nested map.
  • raw_hex — the value’s bytes, when it does not.

An unnamed varint parameter gets value rather than raw_hex, because a varint’s value is its content and there are no bytes to show. That case used to be written as length, which was the varint’s value under a key naming something else entirely.