document the alternative parsing with object field pitfalls

This commit is contained in:
Tom Sydney Kerckhove 2023-09-27 12:17:15 +02:00
parent 483ffe2cb2
commit f3b4c810cd

View File

@ -1586,7 +1586,7 @@ parseAlternatives c rest = go (c :| rest)
-- >>> JSON.parseMaybe (parseJSONVia c) (String "Apple") :: Maybe Fruit
-- Just Apple
--
-- ==== Object fields
-- ==== Required object fields
--
-- >>> data Fruit = Apple | Orange deriving (Show, Eq, Bounded, Enum)
-- >>> let c = shownBoundedEnumCodec
@ -1599,6 +1599,32 @@ parseAlternatives c rest = go (c :| rest)
-- Just Apple
-- >>> JSON.parseMaybe (parseJSONObjectVia o) (KM.fromList [("current",String "Tomato")]) :: Maybe Fruit
-- Nothing
--
-- ==== Required object fields
--
-- While 'parseAlternative' works exactly like you would expect it would with 'requiredField', using 'parseAlterternative' with optional fields has some pitfalls.
--
-- >>> data Fruit = Apple | Orange deriving (Show, Eq, Bounded, Enum)
-- >>> let c = shownBoundedEnumCodec
-- >>> let o = parseAlternative (optionalFieldWith "current" c "current key for this field") (optionalFieldWith "legacy" c "legacy key for this field")
-- >>> toJSONObjectVia o (Just Apple)
-- fromList [("current",String "Apple")]
-- >>> toJSONObjectVia o Nothing
-- fromList []
-- >>> JSON.parseMaybe (parseJSONObjectVia o) (KM.fromList [("current",String "Apple")]) :: Maybe (Maybe Fruit)
-- Just (Just Apple)
--
--
-- ! This is the important result !
-- The second 'optionalFieldWith' is not tried because the first one _succeeds_ in parsing 'Nothing'
--
-- >>> JSON.parseMaybe (parseJSONObjectVia o) (KM.fromList [("legacy",String "Apple")]) :: Maybe (Maybe Fruit)
-- Just Nothing
--
-- Here the parser succeeds as well, because it fails to parse the @current@ field, so it tries to parse the @legacy@ field, which is missing.
--
-- >>> JSON.parseMaybe (parseJSONObjectVia o) (KM.fromList [("current",String "Tomato")]) :: Maybe (Maybe Fruit)
-- Just Nothing
parseAlternative ::
-- | Main codec, for parsing and rendering
Codec context input output ->