@@ -44,6 +44,7 @@ module Data.Aeson.Types.Internal
4444 , parse
4545 , parseEither
4646 , parseMaybe
47+ , parseFail
4748 , modifyFailure
4849 , prependFailure
4950 , parserThrowError
@@ -94,7 +95,6 @@ import Data.HashMap.Strict (HashMap)
9495import Data.Hashable (Hashable(..))
9596import Data.List (intercalate)
9697import Data.Scientific (Scientific)
97−import Data.Semigroup (Semigroup((<>)))
9898import Data.String (IsString(..))
9999import Data.Text (Text, pack, unpack)
100100import Data.Time (UTCTime)
@@ -342,6 +342,10 @@ instance Monoid (Parser a) where
342342 mappend = (<>)
343343 {-# INLINE mappend #-}
344344
345+-- | Raise a parsing failure with some custom message.
346+parseFail :: String -> Parser a
347+parseFail = fail
348+
345349apP :: Parser (a -> b) -> Parser a -> Parser b
346350apP d e = do
347351 b <- d
@@ -581,41 +585,53 @@ data Options = Options
581585 -- the constructor tag. If 'False' the encoding will always
582586 -- follow the `sumEncoding`.
583587 , omitNothingFields :: Bool
584− -- ^ If 'True' record fields with a 'Nothing' value will be
585− -- omitted from the resulting object. If 'False' the resulting
588+ -- ^ If 'True', record fields with a 'Nothing' value will be
589+ -- omitted from the resulting object. If 'False', the resulting
586590 -- object will include those fields mapping to @null@.
587591 --
592+ -- Note that this /does not/ affect parsing: 'Maybe' fields are
593+ -- optional regardless of the value of 'omitNothingFields', subject
594+ -- to the note below.
595+ --
588596 -- === Note
589597 --
590598 -- Setting 'omitNothingFields' to 'True' only affects fields which are of
591− -- type 'Maybe' /uniformly/ in the 'ToJSON' or 'FromJSON' instance. In
592− -- particular, if the type of a field is declared as a type variable, it
599+ -- type 'Maybe' /uniformly/ in the 'ToJSON' instance.
600+ -- In particular, if the type of a field is declared as a type variable, it
593601 -- will not be omitted from the JSON object, unless the field is
594602 -- specialized upfront in the instance.
595603 --
604+ -- The same holds for 'Maybe' fields being optional in the 'FromJSON' instance.
605+ --
596606 -- ==== __Example__
597607 --
598608 -- The generic instance for the following type @Fruit@ depends on whether
599609 -- the instance head is @Fruit a@ or @Fruit (Maybe a)@.
600610 --
601611 -- @
602− -- data Fruit a =
612+ -- data Fruit a = Fruit
603613 -- { apples :: a -- A field whose type is a type variable.
604614 -- , oranges :: 'Maybe' Int
605− -- }
606− --
607− -- options :: 'Options'
608− -- options = 'defaultOptions' { 'omitNothingFields' = 'True' }
615+ -- } deriving 'Generic'
609616 --
610617 -- -- apples required, oranges optional
611618 -- -- Even if 'Data.Aeson.fromJSON' is then specialized to (Fruit ('Maybe' a)).
612− -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit a) where
613− -- 'Data.Aeson.fromJSON' = 'Data.Aeson.genericFromJSON' options
619+ -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit a)
614620 --
615621 -- -- apples optional, oranges optional
616622 -- -- In this instance, the field apples is uniformly of type ('Maybe' a).
617− -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit ('Maybe' a)) where
618− -- 'Data.Aeson.fromJSON' = 'Data.Aeson.genericFromJSON' options
623+ -- instance 'Data.Aeson.FromJSON' a => 'Data.Aeson.FromJSON' (Fruit ('Maybe' a))
624+ --
625+ -- options :: 'Options'
626+ -- options = 'defaultOptions' { 'omitNothingFields' = 'True' }
627+ --
628+ -- -- apples always present in the output, oranges is omitted if 'Nothing'
629+ -- instance 'Data.Aeson.ToJSON' a => 'Data.Aeson.ToJSON' (Fruit a) where
630+ -- 'Data.Aeson.toJSON' = 'Data.Aeson.genericToJSON' options
631+ --
632+ -- -- both apples and oranges are omitted if 'Nothing'
633+ -- instance 'Data.Aeson.ToJSON' a => 'Data.Aeson.ToJSON' (Fruit ('Maybe' a)) where
634+ -- 'Data.Aeson.toJSON' = 'Data.Aeson.genericToJSON' options
619635 -- @
620636 , sumEncoding :: SumEncoding
621637 -- ^ Specifies how to encode constructors of a sum datatype.