Repository navigation
sizes: per-format size rules as data, and vectors that prove them - #4
Merged
Merged
Conversation
added 2 commits
November 11, 2026 07:37
A format's catalog entry gets a closed `sizes` block: the bytes of each primitive, and the header, body, option, struct and enum rules for packed@1, msgpack@1 and json@1, each listing the cases that prove it. profiles/ state them as the catalog does, and the comline-catalog crate holds them as data. vectors/sizes-<format>.json hold 59, 60 and 57 `size` cases: a type, its [min, max], and values written to exactly each end with their bytes. specs/check.sh refuses a rule without cases, a case that proves nothing, and a witness of the wrong length.
added 2 commits
November 11, 2026 07:56
…a vectors file The runtime holds every vectors file to the text it writes back (vectors_write_back_as_read): serde_json's pretty form, every object and array expanded, a float as serde_json writes it. The size vectors were written compact, and f32 1.17549435e-38 as another spelling of the same f32. Same cases, same bytes; only the text changes.
…time renders a vectors file vectors_write_back_as_read holds a vectors file to the text the runtime's conformance crate writes back: a case's input held as a JSON value, so its members sorted by name, and an f32 in it as the f64 it widens to. Same cases, same bytes; only the text changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 1 of per-format sizing: the specification states, as data, how many bytes each kind of value takes in
packed@1,msgpack@1andjson@1, and vectors prove each rule.What it adds
sizeson a format's catalog entry (catalog/schema.cue,#Sizes; closed). Rule kinds, defined incatalog/readme.md:scalars:[min, max]bytes per primitive (bool,u8..u128,s8..s128,f32,f64,char,unit);none,varint_leb128,msgpack_str,msgpack_array,delimited {before, after, between};string(header on the byte length + bodyutf8orjson_escaped, 1-6 bytes a character),array,fixed_array;option {none, some},struct {header, key_extra?},enum {tag: varint_index | name + header};upper_boundon a width, for a max no witness reaches. No official rule needs it.sizes(#FormatProfile.sizes?, optional for custom formats). For an official format#OfficialProfilerequires them equal to the catalog's.sizes-packed,sizes-msgpack,sizes-json, new opsize(59, 60 and 57 cases): a type (#SizeType,#Typeplusfixed_stringforchar[N]),[min, max], and witnesses (min, max, and values between) with their bytes.specs/check.sh(withspecs/sizes.jq, needsjq): every rule listsproven_bycases that exist, are in the rule's feature and format, and show its kind of value in their type; a scalar's rule is proven by that scalar's own case with the same bounds; every case proves a rule; every witness is exactly as long asmin/maxsay, andbetweenones are in range; facts and sizes agree (struct_fields/key_extra,enum_variants/varint_index).comline-catalogcrate:Encoding::sizes,Sizesand its parts,Header::len,sizes(id), generated bycatalog/rust.cue; tests (packedu32is[4, 4], msgpacku64[1, 9], jsons64[1, 20], header tiers, every rule proven in its feature).sizeop, Sizes section).VERSION is not bumped.
The rules, from the runtime's code
char1-4,unit0; varint headers; option tag byte; struct no header; enum varint index.u641-9),u128/s128asbin8(18),charas a string (2-5),unit/absent optionnil; present option is the value; struct is an array; enum is the variant's name as a string.",\, controls (\b \t \n \f \r, others\u00xx), nothing else, so 6 bytes a character at worst;f64is 3-24 bytes andf323-16; absent optionnull(4); struct an object with"name":keys.What proves the bytes
The witnesses' bytes were produced by an independent model of the three encoders that reproduces all 138 existing
format-*encode vectors, not by the runtime. The runtime run in step 2 is the real proof of the bytes, and any mismatch found there is fixed in the spec.check.shhere checks what a file alone can (lengths, references).Not witnessed by a vector
string-max-16384, 65 KB);f64) / 16 (f32): the longest are witnessed, and the bound follows from serde_json's writers (24-byte buffer; an exhaustive check of the one decade that could give anf3217 bytes finds none).Float witnesses use only positional notation, which
ryuandzmij(serde_json before and after 1.0.149) print identically.