Skip to content

Remove concept of the groups module, simplifying generated code. - #2

Merged
rooooooooob merged 2 commits into
masterfrom
remove-groups-module
Apr 10, 2020
Merged

Remove concept of the groups module, simplifying generated code.#2
rooooooooob merged 2 commits into
masterfrom
remove-groups-module

Conversation

@rooooooooob

@rooooooooob rooooooooob commented Apr 10, 2020

Copy link
Copy Markdown
Contributor

Now all field are represented directly inside of the main code,
so instead of both lib.rs having

struct Foo(groups::Foo);

and groups.rs having

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.

TaggedData<T> was also removed to make access within the code-generated library simpler as well. 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.

Before:

struct UntaggedFoo {
    x: uint,
    y: uiny,
}

pub struct Foo {
    data: TaggedData<UntaggedFoo>
}

impl Foo {
    pub fn new(data: UntaggedFoo) -> Self {
        Self { data: data }
    }
}

After:

pub struct Foo {
    x: uint,
    y: uint,
}

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
rooooooooob merged commit e245f3b into master Apr 10, 2020
@rooooooooob
rooooooooob deleted the remove-groups-module branch April 10, 2020 19:43
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant