@@ -763,7 +763,8 @@ consFromJSON jc tName opts instTys cons = do
763763 case sumEncoding opts of
764764 TaggedObject {tagFieldName, contentsFieldName} ->
765765 parseObject $ parseTaggedObject tvMap tagFieldName contentsFieldName
766- TaggedFlatObject {tagFieldName} -> error " unsupported"
766+ TaggedFlatObject {tagFieldName} ->
767+ parseObject $ parseTaggedFlatObject tvMap tagFieldName
767768 UntaggedValue -> error " UntaggedValue: Should be handled already"
768769 ObjectWithSingleField ->
769770 parseObject $ parseObjectWithSingleField tvMap
@@ -814,13 +815,88 @@ consFromJSON jc tName opts instTys cons = do
814815 , noBindS $ parseContents tvMap conKey (Left (valFieldName, obj)) 'conNotFoundFailTaggedObject
815816 ]
816817
817- parseTaggedFlatObject tvMap typFieldName obj = do
818+ parseTaggedFlatObject tvMap tagFieldName obj = do
818819 conKey <- newName " conKey"
819820 doE [ bindS (varP conKey)
820- (infixApp (varE obj) [| (.:) | ] ([| T. pack| ] `appE` stringE typFieldName))
821- , noBindS $ parseContents tvMap conKey (Right obj) 'conNotFoundFailTaggedObject
821+ (infixApp (varE obj) [| (.:) | ] ([| T. pack| ] `appE` stringE tagFieldName))
822+ , noBindS $
823+ caseE (varE conKey)
824+ [ match wildP
825+ ( guardedB $
826+ [ do g <- normalG $ infixApp (varE conKey)
827+ [| (==) | ]
828+ ([| T. pack| ] `appE`
829+ conNameExp opts con)
830+ argTys <- mapM resolveTypeSynonyms (constructorFields con)
831+ let conName = constructorName con
832+ e <- case constructorVariant con of
833+ RecordConstructor fields ->
834+ parseRecord jc tvMap argTys opts tName conName fields obj False
835+ _ ->
836+ parseNumRec tvMap argTys conName obj
837+ return (g, e)
838+ | con <- cons
839+ ]
840+ ++
841+ [ liftM2 (,)
842+ (normalG [e |otherwise|])
843+ ( varE 'conNotFoundFailTaggedObject
844+ `appE` litE (stringL $ show tName)
845+ `appE` listE (map ( litE
846+ . stringL
847+ . constructorTagModifier opts
848+ . nameBase
849+ . constructorName
850+ ) cons
851+ )
852+ `appE` ([| T. unpack| ] `appE` varE conKey)
853+ )
854+ ]
855+ )
856+ []
857+ ]
822858 ]
823859
860+ parseNumRec :: TyVarMap
861+ -> [Type ]
862+ -> Name
863+ -> Name
864+ -> ExpQ
865+ parseNumRec tvMap argTys conName obj =
866+ (if rejectUnknownFields opts
867+ then infixApp checkUnknownRecords [| (>>) | ]
868+ else id ) $
869+ if null argTys
870+ then [| pure | ] `appE` conE conName
871+ else
872+ foldl' (\ a b -> infixApp a [| (<*>) | ] b)
873+ (infixApp (conE conName) [| (<$>) | ] x)
874+ xs
875+ where
876+ fields = map (show :: Int -> String ) $ take (length argTys) [1 .. ]
877+ knownFields = appE [| H. fromList| ] $ listE $
878+ map (\ knownName -> tupE [appE [| T. pack| ] $ litE $ stringL knownName, [| () | ]]) fields
879+ checkUnknownRecords =
880+ caseE (appE [| H. keys| ] $ infixApp (varE obj) [| H. difference| ] knownFields)
881+ [ match (listP [] ) (normalB [| return () | ]) []
882+ , newName " unknownFields" >>=
883+ \ unknownFields -> match (varP unknownFields)
884+ (normalB $ appE [| fail | ] $ infixApp
885+ (litE (stringL " Unknown fields: " ))
886+ [| (++) | ]
887+ (appE [| show | ] (varE unknownFields)))
888+ []
889+ ]
890+ x: xs = [ [| lookupField| ]
891+ `appE` dispatchParseJSON jc conName tvMap argTy
892+ `appE` litE (stringL $ show tName)
893+ `appE` litE (stringL $ constructorTagModifier opts $ nameBase conName)
894+ `appE` varE obj
895+ `appE` ( [| T. pack| ] `appE` stringE field
896+ )
897+ | (field, argTy) <- zip fields argTys
898+ ]
899+
824900 parseUntaggedValue tvMap cons' conVal =
825901 foldr1 (\ e e' -> infixApp e [| (<|>) | ] e')
826902 (map (\ x -> parseValue tvMap x conVal) cons')
0 commit comments