Remove concept of the groups module, simplifying generated code. - #2
Merged
Conversation
Now all field are represented directly inside of the main code,
so instead of both `lib.rs` having
```rust
struct Foo(groups::Foo);
```
and `groups.rs` having
```rust
struct Foo {
x: u32,
y: u32,
}
```
we now have only `lib.rs` having the group structure, but also having the
wasm exposure and other exposed functionality that the `lib.rs` had
before.
This simplifies in-library client code (wasm interface is unchanged)
as instead of `self.0.x.0.y.0` we can just write `self.x.y` and be much
more readable.
This existed before as plain groups and their usage used to be
code-generated in separate steps, as well as a desire to be generic for
both array vs map representations. This does not matter anymore though
as the two (group vs concrete representation) had already became coupled
(and rightfully so) along the way.
Instead of having to do `x.data` everywhere we can directly access the tagged data as `x`. This means we no longer store anything pertaining to tags anywhere except the serializaiton code, making any use from within the generated rust library much less ugly and more obvious, as well as reducing overall code size. We also no longer need to generate those redundant `UntaggedFoo` structs which are contained within the tagged `Foo`, as we can directly generate `Foo` and store the tag information solely within the serialization code without relying on having `TaggedData<UntaggedFoo>` within `Foo`.
rooooooooob
added a commit
that referenced
this pull request
Apr 14, 2020
Group choices as map representation serialization support was added when the last refactor in PR #2
SebastienGllmt
added a commit
that referenced
this pull request
Jul 2, 2026
Generator/runtime product bugs (each verified: compile + CBOR round-trip): - Collections of major-type-7 elements: the array element-loop break-check gated on the whole `Type::Special` class, so `[* float64]` rejected all non-empty input (BreakInDefiniteLen) and `[* bool]` failed to compile. A definite array reads exactly n items and needs no break detection; restrict the check to the indefinite case (Read-only cbor_type/special, so it also compiles inside the reader-erased type-choice closures). `bool` now uses `bool::deserialize` (like the float arms) to avoid an ambiguous `Into` in element position. - Nullable named-collection struct field emitted `Ok(serializer)` twice (E0382, even under --wasm=false): the Optional serialize now mirrors the field's own is_end (statement arms in field position, returning arms at the tail). - Nullable-of-composite across the wasm boundary emitted a blanket `.into()` with no `From<Option<Inner>>` (E0277/E0308): alias-of-Optional and the table get/insert flatten path now map through the Option. - Fixed text literals containing `"`/`\` emitted invalid Rust: escape at the FixedValue::Text emission sites. - `@newtype` on a tagged or parenthesized wrapper was silently dropped (the rule's trailing comment DSL was lost in the single-type unwrap): thread the outer rule's metadata through parse_type so the documented opt-in wrapper works in its natural placement. Test harness: - Nested generated-crate cargo/wasm-pack builds now scrub RUSTFLAGS so CI's `-D warnings` doesn't fail on generated crates' unused imports (the root crate keeps -D warnings via the Build/clippy steps). - emit-tests minter mints unbounded collections at length >=1 so element wire paths actually execute (a broken element type no longer passes vacuously). - verify.ts harness-health gate now covers the containment and control-op loops, not just the feature loop; uncorroborated control-op list keys on any nonzero ruby exit (not only 65) and records the code. - project_corpus dup-[[note]] check; project_robustness catalog cross-check asserts non-empty + missing-direction; loadTomlArray rejects unexpected top-level keys. - structural_rejects: a non-Break special in a definite collection is now a graceful type rejection (more accurate than the old BreakInDefiniteLen), still no abort. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DQr3yzCbgeofMGtjZbCayh
SebastienGllmt
added a commit
that referenced
this pull request
Jul 2, 2026
- corpus_detect: single stateful scan over the whole text so a `;` inside a multi-line `'…'` byte literal can't fabricate a comment/dsl directive; the parenthesized-type detector excludes a keyless inline group directly in a container (`[(uint)]`), which the AST classifies as grpent.inline_group. Added self-check cases for both. - project_golden_hex: the well-formedness walker rejects additional-info 31 (indefinite/break) on majors that have no indefinite form (uint/nint/tag) and a bare break byte, so a malformed head can't mint a bogus cell. - wasm_list_macro_compiles: symmetric anti-vacuity floor for impl_wasm_conversions! (>= 2) in the combined case — previously only the impl_wasm_list! count was asserted, so a regression of the conversions macro compiled green. - New cddl_oracle_dep_rev_matches_cargo_toml test enforces the doc-comment's claim that CDDL_ORACLE_DEP's rev tracks Cargo.toml's cddl rev. - emit_tests::nint_bounds_to_u64 now delegates to the generator's transform (shared pub(crate) fn) instead of a hand-rolled copy that omitted the min/max swap — removing a latent divergence trap for nint reject work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DQr3yzCbgeofMGtjZbCayh
SebastienGllmt
added a commit
that referenced
this pull request
Jul 2, 2026
Three hardening refinements to the spec-anchored KAT suites (audit run #2, slice 12), each hand-derived from RFC 8949 and cross-checked against §A: - Value anchors: kat_preserve!/kat_canonical! now take a mandatory anchor asserting decoded field values hand-read from the input bytes — identity alone cannot catch an exactly-compensating decode+encode bug. Retrofitted to every existing vector. (nint fields store the CBOR argument -1-v, per the emitted write_negative_integer_sz(-(n+1)); anchors assert that.) - Major-type-1 vectors: npair = [n: nint, m: nint] in both suites — the -24/-25 immediate-vs-1-byte boundary, padded 1/2/4/8-byte argument forms, and canonical re-minimization incl. an 8-byte value (arg 2^32) that must KEEP its width. nint was previously anchored only by the circular cbor_int() helper. - Runtime table key sort (previously ZERO golden-hex coverage — only the codegen-time struct sort was pinned): a { * uint => text } holder pins that canonical output sorts keys, tie-breaks bytewise, and — via a key arriving PADDED to a wider head — that the sort compares CANONICAL key bytes, not preserved ones. Mutation-verified: disabling the emitted sort turns both vectors red. The preserve suite gains the mirror vector (key order + padded key heads are data). The cross-major cell that discriminates length-first (RFC 7049 §3.9, the documented rule) from pure-bytewise (RFC 8949 §4.2.1) remains open: the two rules provably coincide for single-major minimal-form keys, and both mixed-major key shapes hit generator compile bugs — newly ledgered in cddl-matrix/ROADMAP.md (int-keyed table: Int never emitted; choice-keyed table under preserve: missing cbor_encodings import) — with the follow-up recorded in TESTING_ROADMAP. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SebastienGllmt
pushed a commit
that referenced
this pull request
Aug 18, 2026
Remove concept of the groups module, simplifying generated code.
SebastienGllmt
pushed a commit
that referenced
this pull request
Aug 18, 2026
Group choices as map representation serialization support was added when the last refactor in PR #2
SebastienGllmt
added a commit
that referenced
this pull request
Aug 18, 2026
Generator/runtime product bugs (each verified: compile + CBOR round-trip): - Collections of major-type-7 elements: the array element-loop break-check gated on the whole `Type::Special` class, so `[* float64]` rejected all non-empty input (BreakInDefiniteLen) and `[* bool]` failed to compile. A definite array reads exactly n items and needs no break detection; restrict the check to the indefinite case (Read-only cbor_type/special, so it also compiles inside the reader-erased type-choice closures). `bool` now uses `bool::deserialize` (like the float arms) to avoid an ambiguous `Into` in element position. - Nullable named-collection struct field emitted `Ok(serializer)` twice (E0382, even under --wasm=false): the Optional serialize now mirrors the field's own is_end (statement arms in field position, returning arms at the tail). - Nullable-of-composite across the wasm boundary emitted a blanket `.into()` with no `From<Option<Inner>>` (E0277/E0308): alias-of-Optional and the table get/insert flatten path now map through the Option. - Fixed text literals containing `"`/`\` emitted invalid Rust: escape at the FixedValue::Text emission sites. - `@newtype` on a tagged or parenthesized wrapper was silently dropped (the rule's trailing comment DSL was lost in the single-type unwrap): thread the outer rule's metadata through parse_type so the documented opt-in wrapper works in its natural placement. Test harness: - Nested generated-crate cargo/wasm-pack builds now scrub RUSTFLAGS so CI's `-D warnings` doesn't fail on generated crates' unused imports (the root crate keeps -D warnings via the Build/clippy steps). - emit-tests minter mints unbounded collections at length >=1 so element wire paths actually execute (a broken element type no longer passes vacuously). - verify.ts harness-health gate now covers the containment and control-op loops, not just the feature loop; uncorroborated control-op list keys on any nonzero ruby exit (not only 65) and records the code. - project_corpus dup-[[note]] check; project_robustness catalog cross-check asserts non-empty + missing-direction; loadTomlArray rejects unexpected top-level keys. - structural_rejects: a non-Break special in a definite collection is now a graceful type rejection (more accurate than the old BreakInDefiniteLen), still no abort. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DQr3yzCbgeofMGtjZbCayh
SebastienGllmt
added a commit
that referenced
this pull request
Aug 18, 2026
- corpus_detect: single stateful scan over the whole text so a `;` inside a multi-line `'…'` byte literal can't fabricate a comment/dsl directive; the parenthesized-type detector excludes a keyless inline group directly in a container (`[(uint)]`), which the AST classifies as grpent.inline_group. Added self-check cases for both. - project_golden_hex: the well-formedness walker rejects additional-info 31 (indefinite/break) on majors that have no indefinite form (uint/nint/tag) and a bare break byte, so a malformed head can't mint a bogus cell. - wasm_list_macro_compiles: symmetric anti-vacuity floor for impl_wasm_conversions! (>= 2) in the combined case — previously only the impl_wasm_list! count was asserted, so a regression of the conversions macro compiled green. - New cddl_oracle_dep_rev_matches_cargo_toml test enforces the doc-comment's claim that CDDL_ORACLE_DEP's rev tracks Cargo.toml's cddl rev. - emit_tests::nint_bounds_to_u64 now delegates to the generator's transform (shared pub(crate) fn) instead of a hand-rolled copy that omitted the min/max swap — removing a latent divergence trap for nint reject work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DQr3yzCbgeofMGtjZbCayh
SebastienGllmt
added a commit
that referenced
this pull request
Aug 18, 2026
Three hardening refinements to the spec-anchored KAT suites (audit run #2, slice 12), each hand-derived from RFC 8949 and cross-checked against §A: - Value anchors: kat_preserve!/kat_canonical! now take a mandatory anchor asserting decoded field values hand-read from the input bytes — identity alone cannot catch an exactly-compensating decode+encode bug. Retrofitted to every existing vector. (nint fields store the CBOR argument -1-v, per the emitted write_negative_integer_sz(-(n+1)); anchors assert that.) - Major-type-1 vectors: npair = [n: nint, m: nint] in both suites — the -24/-25 immediate-vs-1-byte boundary, padded 1/2/4/8-byte argument forms, and canonical re-minimization incl. an 8-byte value (arg 2^32) that must KEEP its width. nint was previously anchored only by the circular cbor_int() helper. - Runtime table key sort (previously ZERO golden-hex coverage — only the codegen-time struct sort was pinned): a { * uint => text } holder pins that canonical output sorts keys, tie-breaks bytewise, and — via a key arriving PADDED to a wider head — that the sort compares CANONICAL key bytes, not preserved ones. Mutation-verified: disabling the emitted sort turns both vectors red. The preserve suite gains the mirror vector (key order + padded key heads are data). The cross-major cell that discriminates length-first (RFC 7049 §3.9, the documented rule) from pure-bytewise (RFC 8949 §4.2.1) remains open: the two rules provably coincide for single-major minimal-form keys, and both mixed-major key shapes hit generator compile bugs — newly ledgered in cddl-matrix/ROADMAP.md (int-keyed table: Int never emitted; choice-keyed table under preserve: missing cbor_encodings import) — with the follow-up recorded in TESTING_ROADMAP. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Now all field are represented directly inside of the main code,
so instead of both
lib.rshavingand
groups.rshavingwe now have only
lib.rshaving the group structure, but also having thewasm exposure and other exposed functionality that the
lib.rshadbefore.
This simplifies in-library client code (wasm interface is unchanged)
as instead of
self.0.x.0.y.0we can just writeself.x.yand be muchmore readable.
This existed before as plain groups and their usage used to be
code-generated in separate steps, as well as a desire to be generic for
both array vs map representations. This does not matter anymore though
as the two (group vs concrete representation) had already became coupled
(and rightfully so) along the way.
TaggedData<T>was also removed to make access within the code-generated library simpler as well. Instead of having to dox.dataeverywhere we can directly accessthe tagged data as
x.This means we no longer store anything pertaining to tags anywhere
except the serializaiton code, making any use from within the generated
rust library much less ugly and more obvious, as well as reducing
overall code size. We also no longer need to generate those redundant
UntaggedFoostructs.Before:
After: