Uh oh!
There was an error while loading. Please reload this page.
Add sum encoding TaggedFlatObject - #828
Conversation
aa1ce47 to
4ec8d6aCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
a24c404 to
c836475CompareIt should now work with GHC 7.* (not sure why my force push didn't trigger CI build) |
poscat0x04
commented
Feb 1, 2021
For some reason, the |
poscat0x04
commented
Feb 1, 2021
@phadej Is this ok now? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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
8f92dbfCompareposcat0x04
commented
Feb 18, 2021
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. |
bergmark
commented
Feb 18, 2021
Guess who has been doing too much JavaScript lately runs away, please disregard |
6dca6d5 to
11cc9beCompare
bergmark
left a comment
There was a problem hiding this comment.
Nice :-)
I actually need this now for a rust API I'm testing!! Should be usable with #[serde(tag = ...)]
bergmark
commented
Feb 26, 2021
I managed to hit some github hot key that posted my review for me... @phadej do you want to look over this again? |
bergmark
commented
Feb 26, 2021
Eh it looks like the tests don't compile, but only on GHC 7.8 :-/ |
phadej
commented
Feb 26, 2021
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). |
bergmark
commented
Feb 26, 2021
You can do it! |
tadfisher
commented
Nov 18, 2021
What's the status of this PR? It would be a useful feature for our codebase, FWIW. |
phadej
commented
Nov 18, 2021
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
SumEncodingvariantTaggedFlatObject :: String -> SumEncodingfor encoding and decoding JSON objects whose tags are on the same level as the contents (hence the name "flat"). The decoding/encoding rule ofTaggedFlatObjectis as follows:TaggedObject)TaggedObject)"$tagFieldName": "$constructorName".For example
A 1 2will 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.