Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: looser interpretation of JSON-encoded variants #413

Open
mjambon opened this issue Sep 7, 2024 · 0 comments
Open

Proposal: looser interpretation of JSON-encoded variants #413

mjambon opened this issue Sep 7, 2024 · 0 comments
Labels
feature request Big and small feature requests

Comments

@mjambon
Copy link
Collaborator

mjambon commented Sep 7, 2024

Various APIs use their own encoding for sum types (variants, tagged unions, etc.). Parsing them with the ATD tools requires writing so-called adapters - currently only supported by atdgen - that rewrite this or that JSON node so as to make it compliant with the format expected by ATD, or vice-versa, for turning an ATD-compliant node into one that conforms to the API.
An example is this format used in some YAML file. Here's the ATD type definition:

type t = [
  | A <json name="a">
  | B <json name="b"> of b
]

type b = {
  ?c: int;
}

Here is a list of valid items of type t. The syntax here is YAML but maps to JSON without issues:

- a
- kind: b
  c: 42
- kind: b
- b
- kind: a

Writing a completely generic adapter for this isn't possible because the adapter needs to know that "b" should be converted to ["b", {}] and that {"kind": "a"} should be converted to "a" to comply with ATD's conventions. As an exercise you can try it and you'll notice that the normalize function needs to be told which constructor expects an argument and which constructor is a simple enum case. This is because normalize doesn't have access to the type definition.

This proposal is to extend what ATD supports when reading variants such that an adapter doesn't need to know whether e.g. constructor b takes an argument or not. If the normalize function reads "b", it will leave it intact instead of having to translate it to ["b", {}]. Similarly, {"kind": "a"} would be translated to ["a", null] (or perhaps ["a", {}]) without having to know whether a takes an argument or not.

Implementing this would require support in all the JSON readers that use adapters as I'm not sure this feature would be useful without adapters (?). The JSON writers would be unaffected.

Disclaimer: this was written hastily on a Friday night. Please ask for clarifications as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Big and small feature requests
Projects
None yet
Development

No branches or pull requests

1 participant