-
-
Notifications
You must be signed in to change notification settings - Fork 616
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
encoding/json: unmarshal uses the first struct in a union of structs #3474
Comments
So this is actually tricky to handle correctly because it has to do a best fit search, and currently it does the "first fit" search. In the case other structs, a missing field might not be an error, so it just gets ignored. |
Other JSON implementations I've seen use a "$Variant" key in the JSON, usually with a string name of the variant (to prevent changes in the union declaration from causing the IDs to shift and break the JSON), using the $ specifically because it's illegal in the language to begin a field name with $ so there won't be any conflicts with actual field names. There's a closed PR I saw a couple of months ago that did something similar, but it wasn't quite right. Would something like this be at all appropriate? I feel it would beat having a field called |
There was a discussion on the discord about making it configurable.
the variant key could use the dollar sign you mentioned. Then there is the question if the variant should store the type name of the variant or the union tag number. I've seen situations where both are more practical:
|
Now that I think about it, the tag number is probably more practical in general, since there's no real reason to reorder an enum (that I can think of?), but there are very good reasons to rename things, but surely it could also be configurable? There's an argument against not "bloating" the configuration though, or providing defaults that could catch someone off-guard. Maybe I need to hop on the Discord 😃 |
Did a draft PR related to this: #4293 In it I added an option to make the marshaller write out the variant name and tag and the unmarshaller is able to look at that data in a backwards compatible way. |
Context
json.unmarshal
seems to be ignoring alternative structs in a union, because if it doesn't find the fields it's looking for on the first struct variant it tries, it parses it as any value, skipping the other possibilities.Odin/core/encoding/json/unmarshal.odin
Lines 461 to 474 in 5b6c96c
Expected Behavior
JSON unmarshalling to
B
instead ofA
, or some sort of error/advisory/workaround.Current Behavior
Invalid type assertion from U to B, actual type: A
Failure Information (for bugs)
Steps to Reproduce
The text was updated successfully, but these errors were encountered: