Issue #1219: Build: the JSON form of an enum variant that carries a payload (ADR-grammar-2 D13)

Open and answer this issue on GitHub.

language, ready · opened 2026-11-03 · updated 2026-11-04 · 2 comments

Decision (owner, 2026-11-03)

ADR-grammar-2 D13 refuses enum variants that carry a payload (NK1250) until their form in JSON is decided. The owner decided it in the conversation on #1020.

Example enum:

enum Zahlung { Bar(i64), Karte(String) }
  1. By default the variant’s name is written into the data, as an object of one member:
    {"zahlung": {"Bar": 1250}}
    {"zahlung": {"Karte": "4111-1111"}}

    This form always works and is never ambiguous.

  2. An enum can opt out of the name with an attribute. The variant is then recognised by the shape of the value:
    {"zahlung": 1250}
    {"zahlung": "4111-1111"}

    The compiler checks when it compiles that no two variants have the same shape. With an added Gutschein(String) the enum above would be refused, because Karte and Gutschein would both be a JSON string.

  3. json::Value is such an enum without a name. Each of its variants has a different shape in JSON: null, a bool, a number, a string, an array, an object. A json::Value field therefore needs no mechanism of its own (#1020) and is read like any enum that opts out of the name.
  4. Other forms are added only when a program needs one:
    • a tag member inside the object: {"typ": "Bar", …}
    • a tag and content side by side: {"t": "Bar", "c": 1250}

Open details (supervisor decides when writing the ADR)

To build

  1. The ADR text, which extends ADR-grammar-2 D13 and §6.
  2. The json package:
    • an arm for an enum with payload variants that reads the one-member object;
    • an arm for an enum without names that chooses the variant by the shape of the next token.
  3. Compile-time check: an enum without names whose variants overlap in shape is refused with a new NK code (supervisor reserves it).
  4. Mark json::Value as an enum without names in the json package, and make a json::Value field readable in json::read[T].
  5. Tests: .nika programs in tests/compiler/ covering:
    • both forms;
    • a refused overlap;
    • a json::Value field.

Comments

keywan-ghadami, 2026-11-04

Owner, 2026-11-04: integer and float are one shape for this check. JSON does not reliably keep the difference. A writer may emit an integer as 5.0, and another writer may emit a float as 5. An enum without names whose variants are, for example, I(i64) and F(f64) is therefore refused, because the variant cannot be chosen safely from the data.


Generated by Claude Code

keywan-ghadami, 2026-11-04

Owner, 2026-11-04, on reading numbers in json::read[T]. This is a neighbouring rule, recorded here because it came up with the shape check:

To build: the number arms of the json package follow this rule, with a .nika test for each of the four cases.


Generated by Claude Code

Back to Open Issues