Skip to content

Commit 4ec8d6a

Browse files
author
Poscat
committed
Implement deriveToJSON for TaggedFlatObject
1 parent af0897f commit 4ec8d6a

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

Data/Aeson/TH.hs

+45-3
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ sumToValue target opts multiCons nullary conName value pairs
421421
content = pairs contentsFieldName
422422
in fromPairsE $
423423
if nullary then tag else infixApp tag [|(Monoid.<>)|] content
424+
TaggedFlatObject {} -> error "impossible"
424425
ObjectWithSingleField ->
425426
objectE [(conString opts conName, value)]
426427
UntaggedValue | nullary -> conStr target opts conName
@@ -434,7 +435,21 @@ argsToValue :: ToJSONFun -> JSONClass -> TyVarMap -> Options -> Bool -> Construc
434435
argsToValue target jc tvMap opts multiCons
435436
ConstructorInfo { constructorName = conName
436437
, constructorVariant = NormalConstructor
437-
, constructorFields = argTys } = do
438+
, constructorFields = argTys }
439+
| TaggedFlatObject{tagFieldName} <- sumEncoding opts
440+
, multiCons = do
441+
let tag = (tagFieldName, conStr target opts conName)
442+
argTys' <- mapM resolveTypeSynonyms argTys
443+
let len = length argTys'
444+
args <- newNameList "arg" len
445+
let os = zipWith (\arg argTy -> dispatchToJSON target jc conName tvMap argTy `appE` varE arg) args argTys'
446+
pairs = zip (fmap (show :: Int -> String) [1..]) os
447+
obj = objectE (tag : pairs)
448+
match (conP conName $ map varP args)
449+
(normalB obj)
450+
[]
451+
| otherwise =
452+
do
438453
argTys' <- mapM resolveTypeSynonyms argTys
439454
let len = length argTys'
440455
args <- newNameList "arg" len
@@ -491,14 +506,33 @@ argsToValue target jc tvMap opts multiCons
491506
else e arg
492507

493508
match (conP conName $ map varP args)
494-
(normalB $ recordSumToValue target opts multiCons (null argTys) conName pairs)
509+
(normalB $ case () of
510+
()
511+
| TaggedFlatObject {tagFieldName} <- sumEncoding opts -> do
512+
let tag = pairE tagFieldName (conStr target opts conName)
513+
fromPairsE $ infixApp tag [|(<>)|] pairs
514+
| otherwise -> recordSumToValue target opts multiCons (null argTys) conName pairs)
495515
[]
496516

497517
-- Infix constructors.
498518
argsToValue target jc tvMap opts multiCons
499519
ConstructorInfo { constructorName = conName
500520
, constructorVariant = InfixConstructor
501-
, constructorFields = argTys } = do
521+
, constructorFields = argTys }
522+
| TaggedFlatObject {tagFieldName} <- sumEncoding opts
523+
, multiCons = do
524+
[alTy, arTy] <- mapM resolveTypeSynonyms argTys
525+
al <- newName "argL"
526+
ar <- newName "argR"
527+
let tag = (tagFieldName, conStr target opts conName)
528+
os = zipWith (\arg argTy -> dispatchToJSON target jc conName tvMap argTy `appE` varE arg) [al, ar] [alTy, arTy]
529+
pairs = zip (fmap (show :: Int -> String) [1..]) os
530+
obj = objectE (tag : pairs)
531+
match (infixP (varP al) conName (varP ar))
532+
(normalB obj)
533+
[]
534+
| otherwise =
535+
do
502536
[alTy, arTy] <- mapM resolveTypeSynonyms argTys
503537
al <- newName "argL"
504538
ar <- newName "argR"
@@ -729,6 +763,7 @@ consFromJSON jc tName opts instTys cons = do
729763
case sumEncoding opts of
730764
TaggedObject {tagFieldName, contentsFieldName} ->
731765
parseObject $ parseTaggedObject tvMap tagFieldName contentsFieldName
766+
TaggedFlatObject {tagFieldName} -> error "unsupported"
732767
UntaggedValue -> error "UntaggedValue: Should be handled already"
733768
ObjectWithSingleField ->
734769
parseObject $ parseObjectWithSingleField tvMap
@@ -779,6 +814,13 @@ consFromJSON jc tName opts instTys cons = do
779814
, noBindS $ parseContents tvMap conKey (Left (valFieldName, obj)) 'conNotFoundFailTaggedObject
780815
]
781816

817+
parseTaggedFlatObject tvMap typFieldName obj = do
818+
conKey <- newName "conKey"
819+
doE [ bindS (varP conKey)
820+
(infixApp (varE obj) [|(.:)|] ([|T.pack|] `appE` stringE typFieldName))
821+
, noBindS $ parseContents tvMap conKey (Right obj) 'conNotFoundFailTaggedObject
822+
]
823+
782824
parseUntaggedValue tvMap cons' conVal =
783825
foldr1 (\e e' -> infixApp e [|(<|>)|] e')
784826
(map (\x -> parseValue tvMap x conVal) cons')

0 commit comments

Comments
 (0)