Skip to content

atdcpp: add <json repr="object"> for sum types (externally-tagged encoding)#489

Merged
mjambon merged 1 commit intoahrefs:masterfrom
mjambon:atdcpp-sum-repr-object
Apr 11, 2026
Merged

atdcpp: add <json repr="object"> for sum types (externally-tagged encoding)#489
mjambon merged 1 commit intoahrefs:masterfrom
mjambon:atdcpp-sum-repr-object

Conversation

@mjambon
Copy link
Copy Markdown
Collaborator

@mjambon mjambon commented Apr 10, 2026

Summary

  • Sum types annotated with <json repr="object"> now encode/decode tagged variants as single-key JSON objects {"Constructor": payload} instead of the default two-element array ["Constructor", payload].
  • Unit variants (no payload) remain plain strings regardless of the repr annotation.
  • Adds a shape type to the test suite with Circle, Square, and Point variants.

Motivation

This encoding matches the Rust/Serde default externally-tagged representation and was already implemented for OCaml in atdml (commit 0fc67a5). It also maps naturally to YAML as a single-key mapping:

# array encoding (default):
- - Circle
  - 3.14
# object encoding (<json repr="object">):
- Circle: 3.14

Uses RapidJSON's StartObject/Key/EndObject API for writing, and IsObject()/MemberBegin()->name for reading — symmetric with the existing StartArray/String/EndArray path.

Test plan

  • dune runtest atdcpp/test — codegen diff test passes (C++ runtime tests require g++ and RapidJSON, not available in CI)

Tagged variants are encoded as single-key JSON objects
{"Constructor": payload} instead of the default two-element array
["Constructor", payload].  This matches the default Rust/Serde
externally-tagged encoding.  It also reads naturally in YAML as a
single-key mapping, which is one motivation for the feature.

Unit variants (no payload) are always encoded as plain strings
regardless of the repr annotation.

The RapidJSON writer uses StartObject/Key/EndObject instead of
StartArray/String/EndArray.  The reader checks x.IsObject() and
extracts the sole member name via MemberBegin()->name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mjambon mjambon merged commit 948706a into ahrefs:master Apr 11, 2026
2 of 3 checks passed
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