-
Notifications
You must be signed in to change notification settings - Fork 323
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
Add sum encoding TaggedFlatObject #828
base: master
Are you sure you want to change the base?
Conversation
aa1ce47
to
4ec8d6a
Compare
a24c404
to
c836475
Compare
It should now work with GHC 7.* (not sure why my force push didn't trigger CI build) |
For some reason, the |
@phadej Is this ok now? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encode single constructor data types with field names as a plain record (This is the same as TaggedObject)
"single constructor data types with field names" = record?
No $tagName
here, or what does "plain record" mean? If there's precedent for this from TaggedObject then perhaps we should keep this, but why does TaggedObject work like that? :-S
Encode multi constructor data types without fields names as a record whose keys are the positions of the fields(starting from 1) and values are the fields encoded as JSON with an additional KV pair "$tagFieldName": "$constructorName". For example A 1 2 will be encoded as {"tag": "A", "1": 1, "2": "2" }.
I think starting at 0 would make more sense as it matches the indices when we use arrays. I would also make the indices ints so that this is closer to an array. Or is there precedent for this elsewhere that I missed?
Note that the tag will overwrite any fields that have the same name.
Can we give an error if this occurs instead, at least in TH? Or will it be more confusing if TH/Generics differ here?
I think there should be some regression tests on all the functionality. We have some in NullaryConstructors.hs now but It's hard to tell how this will behave with other shapes of data types.
512ac2f
to
8f92dbf
Compare
Plain record just means a record without any additional field.
Yeah, that makes sense. TBH the current choice of encoding constructors without field names is a bit arbitrary. I initially did not plan to support them but then figured out it would affect other
I'm not sure if I understand. JSON keys must be strings, right?
Yeah, I think they should have the same behavior. |
Guess who has been doing too much JavaScript lately runs away, please disregard |
6dca6d5
to
11cc9be
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice :-)
I actually need this now for a rust API I'm testing!! Should be usable with #[serde(tag = ...)]
I managed to hit some github hot key that posted my review for me... @phadej do you want to look over this again? |
Eh it looks like the tests don't compile, but only on GHC 7.8 :-/ |
The issue test-failure issue might be something which will get fixed with #839. I think I can wipe out all use over overlapping instances for good. Just need to get to it. (And get courage to commit a breaking change). |
You can do it! |
What's the status of this PR? It would be a useful feature for our codebase, FWIW. |
My current opinion is to throw Current generics and template haskell code is very much unmaintainable (as it tries to do evertything), so this PR is probably not going anywhere anytime soon. |
Closes #827
This PR adds a
SumEncoding
variantTaggedFlatObject :: String -> SumEncoding
for encoding and decoding JSON objects whose tags are on the same level as the contents (hence the name "flat"). The decoding/encoding rule ofTaggedFlatObject
is as follows:TaggedObject
)TaggedObject
)"$tagFieldName": "$constructorName"
.For example
A 1 2
will be encoded as{"tag": "A", "1": 1, "2": "2" }
.Note that the tag will overwrite any fields that have the same name.
"$tagFieldName" : "$constructorName"
For example
A { field1 = 1, field2 = "2" }
will be encoded as{"tag": "A", "field1": 1, "field2": "2" }
.Note that the tag will overwrite any fields that have the same name.