-
Notifications
You must be signed in to change notification settings - Fork 15
wit/bindgen: support JSON encoding of WIT types #239
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
Comments
Can we move the design and task list for this to an issue? Then we can have discrete PRs that implement JSON support for different types? |
Proposal for OptionThe current proposal specifies An alternate proposal would be to specify For an {"some":"foo"} For an {"none":null} For an {"some":{"none":null}} Result
For {"ok": "some OK value"} For {"error": null} |
For |
Inspired by #301, I think
|
@ydnar would love to discuss that a bit, I think that representing option values in that way gives us the best ability to understand when it's a Generally what I would expect an optional field to be in JSON is either omitting the field entirely or having the field be set to What I have in my PR corresponds to the following behavior:
|
Is it a goal to support symmetrical round-trip of WIT values to JSON? If so, then this would require unambiguous encoding of Given a WIT type
How should these be serialized?
Or:
Using |
Well, honestly I'm not sure. I know that practically from a WIT perspective we would want to symmetrically marshal/unmarshal, but from a JSON perspective there's not a way to represent nested optionals so we either have to have a WIT-specific structure or lose information. My goal personally in the contribution / thinking is to marshal the option type in a way that would be compatible with existing tools as much as possible. Ideally, a Do you think that this is a reasonable tradeoff to accept into the marshaling implementation or do we need to have symmetric marshaling/unmarshaling? It may be valuable to consider your proposal for the |
Can you explain what you mean? A mechanism for representing nested options is proposed earlier in this thread: #239 (comment) |
@ydnar I don't mean to say it's not possible, just that I'm not aware of existing libraries that would parse the |
The client will need to model result types as well. This is just a form of that. Noted Serde has long-standing issues with double options: https://docs.rs/serde_with/latest/x86_64-apple-darwin/serde_with/rust/double_option/index.html |
Seems like it would be great to be able to decide what kind of tagging to use for marshaling/unmarshaling in an ideal world. https://serde.rs/enum-representations.html I'm looking for untagged here for compatibility, but externally tagged allows for symmetry. I don't know if there's a way to mark a specific field to change the tagging, would this be possible to specify to wit-bindgen-go in some way? Ultimately looking to enable the flexibility for a user of wit-bindgen-go to choose |
@ydnar since there's a couple of different goals for JSON de/serialization, do you think it would be possible for us to allow specifying options to Ideally it would be great to supply the best marshaling behavior based on the use case, and what JSON tools you're working with on the other end. I'd be happy to help contribute this if this feels reasonable |
I think we should start with a proposal. Ideally in the component model repository, as a Markdown file that describes a serialization format, goals, non-goals, etc. Then we can align this code generator to that. |
I actually ran into a problem using a WIT generated data structure, which I was using to represent a OpenAI API request. I noticed the json tags generated and was delighted to use them to marshal the generated structure to json for use in the HTTP API request to OAI. Unfortunately the optional fields were not tagged with It would be nice to be able to either default to optionals being |
This started in #225
Goal: JSON Serialize / Deserialize WIT Records based on WIT field names.
Progress
record
- wit/bindgen: Add JSON tag to Record structs #265list
- cm: Implement json Marshal/Unmarshal for List type #266enum
tuple
variant
result
option
resource
handle types (decide behavior)error-context
stream
future
Approach
Centralize JSON serialization in the
cm
package, keeping codegen changes to a minimum.Given a complex record type:
and filling it up:
We should serialize it to JSON as:
For comparison, this is what is produced today:
Type encoding
Whenever possible, reuse standard mappings. string -> string, u32 -> uint32, etc.
Tuple handling
Tuples are encoded as json arrays with explicit
null
s.Variant handling
Variants are encoded as json dictionaries, so they can carry the variant data.
Option handling
Options rely on explicit
null
for the "None" case.Questions
Zero Value Variants
Today they end up with
tag = 0
, this impacts de-serialization of variants. We need the ability to distinct between:var v Variant
v := NewVariantWithZeroTagValue()
v := Some(NewVariantWithZeroTagValue)
atm only the
Some()
path de-serializes correctly ( pointers ).The text was updated successfully, but these errors were encountered: