@@ -763,7 +763,8 @@ consFromJSON jc tName opts instTys cons = do
763
763
case sumEncoding opts of
764
764
TaggedObject {tagFieldName, contentsFieldName} ->
765
765
parseObject $ parseTaggedObject tvMap tagFieldName contentsFieldName
766
- TaggedFlatObject {tagFieldName} -> error " unsupported"
766
+ TaggedFlatObject {tagFieldName} ->
767
+ parseObject $ parseTaggedFlatObject tvMap tagFieldName
767
768
UntaggedValue -> error " UntaggedValue: Should be handled already"
768
769
ObjectWithSingleField ->
769
770
parseObject $ parseObjectWithSingleField tvMap
@@ -814,13 +815,88 @@ consFromJSON jc tName opts instTys cons = do
814
815
, noBindS $ parseContents tvMap conKey (Left (valFieldName, obj)) 'conNotFoundFailTaggedObject
815
816
]
816
817
817
- parseTaggedFlatObject tvMap typFieldName obj = do
818
+ parseTaggedFlatObject tvMap tagFieldName obj = do
818
819
conKey <- newName " conKey"
819
820
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
+ ]
822
858
]
823
859
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
+
824
900
parseUntaggedValue tvMap cons' conVal =
825
901
foldr1 (\ e e' -> infixApp e [| (<|>) | ] e')
826
902
(map (\ x -> parseValue tvMap x conVal) cons')
0 commit comments