Skip to content

feat(schema): distinguish input vs output JSON schemas (closes #2508) - #2563

Open
genisis0x wants to merge 1 commit into
stephenberry:mainfrom
genisis0x:fix/issue-2508-schema-input-output
Open

feat(schema): distinguish input vs output JSON schemas (closes #2508)#2563
genisis0x wants to merge 1 commit into
stephenberry:mainfrom
genisis0x:fix/issue-2508-schema-input-output

Conversation

@genisis0x

Copy link
Copy Markdown
Contributor

Summary

Closes #2508.

Glaze previously emitted a single JSON Schema for every type even though serialization and parsing contracts differ. The mixed behavior — required on objects but no minItems on tuples after #2461 — described neither contract fully.

This PR introduces schema_purpose { input, output } and threads it through to_json_schema via an opts_with_schema_purpose wrapper that carries the tag in the existing constexpr Opts.

New entry points:

  • glz::write_json_input_schema<T>() — partial-parse friendly: no required on objects, no minItems on tuples.
  • glz::write_json_output_schema<T>() — serialization contract: required listed for guaranteed-present keys, minItems == maxItems on tuples.

glz::write_json_schema<T>() keeps its existing signature and now defaults to output purpose. For objects this preserves the existing required emission; for tuples this newly emits minItems == maxItems, completing the output-schema contract.

User-provided meta<V>::required is always honored regardless of purpose, since it expresses a developer-asserted parsing requirement. Variant discriminator tags also stay in required for input schemas because the tag must be present to select an alternative.

Test plan

  • jsonschema_test builds cleanly.
  • Updated tuple schema uses prefixItems expected string to include minItems.
  • New schema_purpose_test suite covers:
    • input schema for tuples omits minItems,
    • output schema for tuples sets minItems == maxItems,
    • input schema for objects omits required (with error_on_missing_keys),
    • output schema for objects lists non-nullable members in required,
    • default write_json_schema matches output purpose.

…2508)

Glaze previously emitted a single JSON Schema for every type even though the
serialization and parsing contracts differ. Output guarantees every non-skipped
key is written and that tuples are emitted at full length; input permits
partial objects (no `required`) and partial tuples (no `minItems`). The mixed
behavior — emitting `required` on objects but omitting `minItems` on tuples
(see stephenberry#2461) — described neither contract fully.

Introduce `schema_purpose { input, output }` and thread it through
`to_json_schema` via an `opts_with_schema_purpose` wrapper that carries the
tag in the existing constexpr Opts. New entry points:

- `write_json_input_schema<T>()` — partial-parse friendly: no `required` on
  objects, no `minItems` on tuples.
- `write_json_output_schema<T>()` — serialization contract: `required` listed
  for guaranteed-present keys, `minItems == maxItems` on tuples.

`write_json_schema` keeps its existing signature and defaults to `output`,
which preserves the existing `required` behavior on objects and additionally
emits `minItems` on tuples so output schemas now fully describe what glaze
serializes.

User-provided `meta<V>::required` is always honored regardless of purpose,
since it expresses a developer-asserted parsing requirement. Variant
discriminator tags also remain in `required` for input schemas because the
tag must be present for the parser to select an alternative.
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.

glaze silently has different JSON schemas for parsing and serializaition due to partial parsing

1 participant