Skip to content

Add allNullaryConstructorTagModifier option #1143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Data/Aeson.hs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ module Data.Aeson
, fieldLabelModifier
, constructorTagModifier
, allNullaryToStringTag
, allNullaryConstructorTagModifier
, omitNothingFields
, allowOmittedFields
, sumEncoding
Expand Down
12 changes: 10 additions & 2 deletions src/Data/Aeson/TH.hs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ consToValue target jc opts instTys cons = autoletE liftSBS $ \letInsert -> do
-- forgotten.
[con] | not (tagSingleConstructors opts) -> [argsToValue letInsert target jc tvMap opts False con]
_ | allNullaryToStringTag opts && all isNullary cons ->
[ match (conP conName []) (normalB $ conStr target opts conName) []
let opts' = opts { constructorTagModifier =
fromMaybe (constructorTagModifier opts)
(allNullaryConstructorTagModifier opts)
} in
[ match (conP conName []) (normalB $ conStr target opts' conName) []
| con <- cons
, let conName = constructorName con
]
Expand Down Expand Up @@ -682,13 +686,17 @@ consFromJSON jc tName opts instTys cons = do
else mixedMatches tvMap

allNullaryMatches =
let opts' = opts { constructorTagModifier =
fromMaybe (constructorTagModifier opts)
(allNullaryConstructorTagModifier opts)
} in
[ do txt <- newName "txtX"
match (conP 'String [varP txt])
(guardedB $
[ liftM2 (,) (normalG $
infixApp (varE txt)
[|(==)|]
(conTxt opts conName)
(conTxt opts' conName)
)
([|pure|] `appE` conE conName)
| con <- cons
Expand Down
1 change: 1 addition & 0 deletions src/Data/Aeson/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ module Data.Aeson.Types
, fieldLabelModifier
, constructorTagModifier
, allNullaryToStringTag
, allNullaryConstructorTagModifier
, omitNothingFields
, allowOmittedFields
, sumEncoding
Expand Down
3 changes: 2 additions & 1 deletion src/Data/Aeson/Types/FromJSON.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,8 @@ parseAllNullarySum tname opts =
badTag tag = failWithCTags tname modifier $ \cnames ->
"expected one of the tags " ++ show cnames ++
", but found tag " ++ show tag
modifier = constructorTagModifier opts
modifier = fromMaybe (constructorTagModifier opts)
(allNullaryConstructorTagModifier opts)

-- | Fail with an informative error message about a mismatched tag.
-- The error message is parameterized by the list of expected tags,
Expand Down
27 changes: 17 additions & 10 deletions src/Data/Aeson/Types/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ module Data.Aeson.Types.Internal
fieldLabelModifier
, constructorTagModifier
, allNullaryToStringTag
, allNullaryConstructorTagModifier
, omitNothingFields
, allowOmittedFields
, sumEncoding
Expand Down Expand Up @@ -714,6 +715,10 @@ data Options = Options
-- nullary constructors, will be encoded to just a string with
-- the constructor tag. If 'False' the encoding will always
-- follow the `sumEncoding`.
, allNullaryConstructorTagModifier :: Maybe (String -> String)
-- ^ If not 'Nothing', specifies the function to be used instead of
-- 'constructorTagModifier' whenever 'allNullaryToStringTag'
-- is in effect. Useful for encoding enums specially.
, omitNothingFields :: Bool
-- ^ If 'True', record fields with a 'Nothing' value will be
-- omitted from the resulting object. If 'False', the resulting
Expand Down Expand Up @@ -744,12 +749,13 @@ data Options = Options
}

instance Show Options where
show (Options f c a o q s u t r) =
show (Options f c a ac o q s u t r) =
"Options {"
++ intercalate ", "
[ "fieldLabelModifier =~ " ++ show (f "exampleField")
, "constructorTagModifier =~ " ++ show (c "ExampleConstructor")
, "allNullaryToStringTag = " ++ show a
, "allNullaryConstructorTagModifier =~ " ++ show (($ "ExampleConstructor") <$> ac)
, "omitNothingFields = " ++ show o
, "allowOmittedFields = " ++ show q
, "sumEncoding = " ++ show s
Expand Down Expand Up @@ -843,15 +849,16 @@ data JSONKeyOptions = JSONKeyOptions
-- @
defaultOptions :: Options
defaultOptions = Options
{ fieldLabelModifier = id
, constructorTagModifier = id
, allNullaryToStringTag = True
, omitNothingFields = False
, allowOmittedFields = True
, sumEncoding = defaultTaggedObject
, unwrapUnaryRecords = False
, tagSingleConstructors = False
, rejectUnknownFields = False
{ fieldLabelModifier = id
, constructorTagModifier = id
, allNullaryToStringTag = True
, allNullaryConstructorTagModifier = Nothing
, omitNothingFields = False
, allowOmittedFields = True
, sumEncoding = defaultTaggedObject
, unwrapUnaryRecords = False
, tagSingleConstructors = False
, rejectUnknownFields = False
}

-- | Default 'TaggedObject' 'SumEncoding' options:
Expand Down
4 changes: 3 additions & 1 deletion src/Data/Aeson/Types/ToJSON.hs
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,9 @@ instance ( GetConName f
where
sumToJSON opts targs
| allNullaryToStringTag opts = Tagged . fromString
. constructorTagModifier opts . getConName
. fromMaybe (constructorTagModifier opts)
(allNullaryConstructorTagModifier opts)
. getConName
| otherwise = Tagged . nonAllNullarySumToJSON opts targs
{-# INLINE sumToJSON #-}

Expand Down
1 change: 1 addition & 0 deletions tests/UnitTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ showOptions =
++ "fieldLabelModifier =~ \"exampleField\""
++ ", constructorTagModifier =~ \"ExampleConstructor\""
++ ", allNullaryToStringTag = True"
++ ", allNullaryConstructorTagModifier =~ Nothing"
++ ", omitNothingFields = False"
++ ", allowOmittedFields = True"
++ ", sumEncoding = TaggedObject {tagFieldName = \"tag\", contentsFieldName = \"contents\"}"
Expand Down