Skip to content

Commit 1175bcc

Browse files
committed
allNullaryConstructorTagModifier
1 parent cb75115 commit 1175bcc

File tree

7 files changed

+35
-14
lines changed

7 files changed

+35
-14
lines changed

src/Data/Aeson.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ module Data.Aeson
131131
, fieldLabelModifier
132132
, constructorTagModifier
133133
, allNullaryToStringTag
134+
, allNullaryConstructorTagModifier
134135
, omitNothingFields
135136
, allowOmittedFields
136137
, sumEncoding

src/Data/Aeson/TH.hs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,11 @@ consToValue target jc opts instTys cons = autoletE liftSBS $ \letInsert -> do
335335
-- forgotten.
336336
[con] | not (tagSingleConstructors opts) -> [argsToValue letInsert target jc tvMap opts False con]
337337
_ | allNullaryToStringTag opts && all isNullary cons ->
338-
[ match (conP conName []) (normalB $ conStr target opts conName) []
338+
let opts' = opts { constructorTagModifier =
339+
fromMaybe (constructorTagModifier opts)
340+
(allNullaryConstructorTagModifier opts)
341+
} in
342+
[ match (conP conName []) (normalB $ conStr target opts' conName) []
339343
| con <- cons
340344
, let conName = constructorName con
341345
]
@@ -682,13 +686,17 @@ consFromJSON jc tName opts instTys cons = do
682686
else mixedMatches tvMap
683687

684688
allNullaryMatches =
689+
let opts' = opts { constructorTagModifier =
690+
fromMaybe (constructorTagModifier opts)
691+
(allNullaryConstructorTagModifier opts)
692+
} in
685693
[ do txt <- newName "txtX"
686694
match (conP 'String [varP txt])
687695
(guardedB $
688696
[ liftM2 (,) (normalG $
689697
infixApp (varE txt)
690698
[|(==)|]
691-
(conTxt opts conName)
699+
(conTxt opts' conName)
692700
)
693701
([|pure|] `appE` conE conName)
694702
| con <- cons

src/Data/Aeson/Types.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ module Data.Aeson.Types
142142
, fieldLabelModifier
143143
, constructorTagModifier
144144
, allNullaryToStringTag
145+
, allNullaryConstructorTagModifier
145146
, omitNothingFields
146147
, allowOmittedFields
147148
, sumEncoding

src/Data/Aeson/Types/FromJSON.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,8 @@ parseAllNullarySum tname opts =
11281128
badTag tag = failWithCTags tname modifier $ \cnames ->
11291129
"expected one of the tags " ++ show cnames ++
11301130
", but found tag " ++ show tag
1131-
modifier = constructorTagModifier opts
1131+
modifier = fromMaybe (constructorTagModifier opts)
1132+
(allNullaryConstructorTagModifier opts)
11321133

11331134
-- | Fail with an informative error message about a mismatched tag.
11341135
-- The error message is parameterized by the list of expected tags,

src/Data/Aeson/Types/Internal.hs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ module Data.Aeson.Types.Internal
5656
fieldLabelModifier
5757
, constructorTagModifier
5858
, allNullaryToStringTag
59+
, allNullaryConstructorTagModifier
5960
, omitNothingFields
6061
, allowOmittedFields
6162
, sumEncoding
@@ -714,6 +715,10 @@ data Options = Options
714715
-- nullary constructors, will be encoded to just a string with
715716
-- the constructor tag. If 'False' the encoding will always
716717
-- follow the `sumEncoding`.
718+
, allNullaryConstructorTagModifier :: Maybe (String -> String)
719+
-- ^ If not 'Nothing', specifies the function to be used instead of
720+
-- 'constructorTagModifier' whenever 'allNullaryToStringTag'
721+
-- is in effect. Useful for encoding enums specially.
717722
, omitNothingFields :: Bool
718723
-- ^ If 'True', record fields with a 'Nothing' value will be
719724
-- omitted from the resulting object. If 'False', the resulting
@@ -744,12 +749,13 @@ data Options = Options
744749
}
745750

746751
instance Show Options where
747-
show (Options f c a o q s u t r) =
752+
show (Options f c a ac o q s u t r) =
748753
"Options {"
749754
++ intercalate ", "
750755
[ "fieldLabelModifier =~ " ++ show (f "exampleField")
751756
, "constructorTagModifier =~ " ++ show (c "ExampleConstructor")
752757
, "allNullaryToStringTag = " ++ show a
758+
, "allNullaryConstructorTagModifier =~ " ++ show (($ "ExampleConstructor") <$> ac)
753759
, "omitNothingFields = " ++ show o
754760
, "allowOmittedFields = " ++ show q
755761
, "sumEncoding = " ++ show s
@@ -843,15 +849,16 @@ data JSONKeyOptions = JSONKeyOptions
843849
-- @
844850
defaultOptions :: Options
845851
defaultOptions = Options
846-
{ fieldLabelModifier = id
847-
, constructorTagModifier = id
848-
, allNullaryToStringTag = True
849-
, omitNothingFields = False
850-
, allowOmittedFields = True
851-
, sumEncoding = defaultTaggedObject
852-
, unwrapUnaryRecords = False
853-
, tagSingleConstructors = False
854-
, rejectUnknownFields = False
852+
{ fieldLabelModifier = id
853+
, constructorTagModifier = id
854+
, allNullaryToStringTag = True
855+
, allNullaryConstructorTagModifier = Nothing
856+
, omitNothingFields = False
857+
, allowOmittedFields = True
858+
, sumEncoding = defaultTaggedObject
859+
, unwrapUnaryRecords = False
860+
, tagSingleConstructors = False
861+
, rejectUnknownFields = False
855862
}
856863

857864
-- | Default 'TaggedObject' 'SumEncoding' options:

src/Data/Aeson/Types/ToJSON.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,9 @@ instance ( GetConName f
938938
where
939939
sumToJSON opts targs
940940
| allNullaryToStringTag opts = Tagged . fromString
941-
. constructorTagModifier opts . getConName
941+
. fromMaybe (constructorTagModifier opts)
942+
(allNullaryConstructorTagModifier opts)
943+
. getConName
942944
| otherwise = Tagged . nonAllNullarySumToJSON opts targs
943945
{-# INLINE sumToJSON #-}
944946

tests/UnitTests.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ showOptions =
278278
++ "fieldLabelModifier =~ \"exampleField\""
279279
++ ", constructorTagModifier =~ \"ExampleConstructor\""
280280
++ ", allNullaryToStringTag = True"
281+
++ ", allNullaryConstructorTagModifier =~ Nothing"
281282
++ ", omitNothingFields = False"
282283
++ ", allowOmittedFields = True"
283284
++ ", sumEncoding = TaggedObject {tagFieldName = \"tag\", contentsFieldName = \"contents\"}"

0 commit comments

Comments
 (0)