{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

-- TODO: Drop this when we remove support for Data.Attoparsec.Number
{-# OPTIONS_GHC -fno-warn-deprecations #-}

module Data.Aeson.Types.FromJSON
    (
    -- * Core JSON classes
      FromJSON(..)
    -- * Liftings to unary and binary type constructors
    , FromJSON1(..)
    , parseJSON1
    , omittedField1
    , FromJSON2(..)
    , parseJSON2
    , omittedField2
    -- * Generic JSON classes
    , GFromJSON(..)
    , FromArgs(..)
    , genericParseJSON
    , genericLiftParseJSON
    -- * Classes and types for map keys
    , FromJSONKey(..)
    , FromJSONKeyFunction(..)
    , fromJSONKeyCoerce
    , coerceFromJSONKeyFunction
    , mapFromJSONKeyFunction

    , GFromJSONKey()
    , genericFromJSONKey

    -- * List functions
    , listParser

    -- * Inspecting @'Value's@
    , withObject
    , withText
    , withArray
    , withScientific
    , withBool
    , withEmbeddedJSON

    -- * Functions
    , fromJSON
    , ifromJSON
    , typeMismatch
    , unexpected
    , parseField
    , parseFieldMaybe
    , parseFieldMaybe'
    , parseFieldOmit
    , parseFieldOmit'
    , explicitParseField
    , explicitParseFieldMaybe
    , explicitParseFieldMaybe'
    , explicitParseFieldOmit
    , explicitParseFieldOmit'
    , parseIndexedJSON
    -- ** Operators
    , (.:)
    , (.:?)
    , (.:!)
    , (.!=)
    , (.:?=)
    , (.:!=)
    -- * Internal
    , parseOptionalFieldWith
    ) where

import Data.Aeson.Internal.Prelude

import Control.Monad (zipWithM, guard)
import Data.Aeson.Internal.Functions (mapKey, mapKeyO)
import Data.Aeson.Internal.Scientific
import Data.Aeson.Types.Generic
import Data.Aeson.Types.Internal
import Data.Aeson.Decoding.ByteString.Lazy
import Data.Aeson.Decoding.Conversion (unResult, toResultValue, lbsSpace)
import Data.Bits (unsafeShiftR)
import Data.Fixed (Fixed, HasResolution (resolution), Nano)
import Data.Functor.Compose (Compose(..))
import Data.Functor.Identity (Identity(..))
import Data.Functor.Product (Product(..))
import Data.Functor.Sum (Sum(..))
import Data.Functor.These (These1 (..))
import Data.Hashable (Hashable(..))
import Data.List.NonEmpty (NonEmpty(..))
import Data.Ord (Down (..))
import Data.Ratio ((%), Ratio)
import Data.Scientific (base10Exponent)
import Data.Tagged (Tagged(..))
import Data.Text (pack, unpack)
import Data.These (These (..))
import Data.Time (Day, DiffTime, LocalTime, NominalDiffTime, TimeOfDay, ZonedTime)
import Data.Time.Calendar.Compat (CalendarDiffDays (..), DayOfWeek (..))
import Data.Time.Calendar.Month.Compat (Month)
import Data.Time.Calendar.Quarter.Compat (Quarter, QuarterOfYear (..))
import Data.Time.LocalTime.Compat (CalendarDiffTime (..))
import Data.Time.Clock.System.Compat (SystemTime (..))
import Data.Time.Format.Compat (parseTimeM, defaultTimeLocale)
import Data.Traversable as Tr (sequence)
import Data.Tuple.Solo (Solo (..))
import Data.Type.Coercion (Coercion (..))
import Data.Version (Version, parseVersion)
import Foreign.Storable (Storable)
import Foreign.C.Types (CTime (..))
import GHC.Generics
import Text.ParserCombinators.ReadP (readP_to_S)
import Unsafe.Coerce (unsafeCoerce)
import qualified Data.Aeson.Parser.Time as Time
import qualified Data.Aeson.Key as Key
import qualified Data.Aeson.KeyMap as KM
import qualified Data.ByteString.Lazy as L
import qualified Data.DList as DList
import qualified Data.DList.DNonEmpty as DNE
import qualified Data.Fix as F
import qualified Data.HashMap.Strict as H
import qualified Data.HashSet as HashSet
import qualified Data.IntMap as IntMap
import qualified Data.IntSet as IntSet
import qualified Data.Map as M
import qualified Data.Monoid as Monoid
import qualified Data.Scientific as Scientific
import qualified Data.Semigroup as Semigroup
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import qualified Data.Strict as S
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy as LT
import qualified Data.Text.Short as ST
import qualified Data.Tree as Tree
import qualified Data.UUID.Types as UUID
import qualified Data.Vector as V
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Primitive as VP
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Unboxed as VU
import qualified Network.URI as URI

import qualified GHC.Exts as Exts
import qualified Data.Primitive.Array as PM
import qualified Data.Primitive.SmallArray as PM
import qualified Data.Primitive.Types as PM
import qualified Data.Primitive.PrimArray as PM

#if __GLASGOW_HASKELL__ < 804
import qualified Data.Type.Coercion
#endif

parseIndexedJSON :: (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON :: forall a. (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON Value -> Parser a
p Int
idx Value
value = Value -> Parser a
p Value
value forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
idx

parseIndexedJSONPair :: (Value -> Parser a) -> (Value -> Parser b) -> Int -> Value -> Parser (a, b)
parseIndexedJSONPair :: forall a b.
(Value -> Parser a)
-> (Value -> Parser b) -> Int -> Value -> Parser (a, b)
parseIndexedJSONPair Value -> Parser a
keyParser Value -> Parser b
valParser Int
idx Value
value = Value -> Parser (a, b)
p Value
value forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
idx
  where
    p :: Value -> Parser (a, b)
p = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"(k, v)" forall a b. (a -> b) -> a -> b
$ \Array
ab ->
        let n :: Int
n = forall a. Vector a -> Int
V.length Array
ab
        in if Int
n forall a. Eq a => a -> a -> Bool
== Int
2
             then (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (Value -> Parser a) -> Int -> Array -> Parser a
parseJSONElemAtIndex Value -> Parser a
keyParser Int
0 Array
ab
                      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. (Value -> Parser a) -> Int -> Array -> Parser a
parseJSONElemAtIndex Value -> Parser b
valParser Int
1 Array
ab
             else forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"cannot unpack array of length " forall a. [a] -> [a] -> [a]
++
                         forall a. Show a => a -> String
show Int
n forall a. [a] -> [a] -> [a]
++ String
" into a pair"

parseJSONElemAtIndex :: (Value -> Parser a) -> Int -> V.Vector Value -> Parser a
parseJSONElemAtIndex :: forall a. (Value -> Parser a) -> Int -> Array -> Parser a
parseJSONElemAtIndex Value -> Parser a
p Int
idx Array
ary = Value -> Parser a
p (forall a. Vector a -> Int -> a
V.unsafeIndex Array
ary Int
idx) forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
idx

parseRealFloat :: RealFloat a => String -> Value -> Parser a
parseRealFloat :: forall a. RealFloat a => String -> Value -> Parser a
parseRealFloat String
_    (Number Scientific
s)      = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. RealFloat a => Scientific -> a
Scientific.toRealFloat Scientific
s
parseRealFloat String
_    Value
Null            = forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
0forall a. Fractional a => a -> a -> a
/a
0)
parseRealFloat String
_    (String Text
"-inf") = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Num a => a -> a
negate a
1forall a. Fractional a => a -> a -> a
/a
0)
parseRealFloat String
_    (String Text
"+inf") = forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
1forall a. Fractional a => a -> a -> a
/a
0)
parseRealFloat String
name Value
v               = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. Value -> Parser a
unexpected Value
v)

parseIntegralFromScientific :: forall a. Integral a => Scientific -> Parser a
parseIntegralFromScientific :: forall a. Integral a => Scientific -> Parser a
parseIntegralFromScientific Scientific
s =
    case forall r i. (RealFloat r, Integral i) => Scientific -> Either r i
Scientific.floatingOrInteger Scientific
s :: Either Double a of
        Right a
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
x
        Left Double
_  -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unexpected floating number " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Scientific
s

parseIntegral :: Integral a => String -> Value -> Parser a
parseIntegral :: forall a. Integral a => String -> Value -> Parser a
parseIntegral String
name =
    forall a. String -> Parser a -> Parser a
prependContext String
name forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific' forall a. Integral a => Scientific -> Parser a
parseIntegralFromScientific

parseBoundedIntegralFromScientific :: (Bounded a, Integral a) => Scientific -> Parser a
parseBoundedIntegralFromScientific :: forall a. (Bounded a, Integral a) => Scientific -> Parser a
parseBoundedIntegralFromScientific Scientific
s = forall b a. b -> (a -> b) -> Maybe a -> b
maybe
    (forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"value is either floating or will cause over or underflow " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Scientific
s)
    forall (f :: * -> *) a. Applicative f => a -> f a
pure
    (forall i. (Integral i, Bounded i) => Scientific -> Maybe i
Scientific.toBoundedInteger Scientific
s)

parseBoundedIntegral :: (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral :: forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
name =
    forall a. String -> Parser a -> Parser a
prependContext String
name forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Scientific -> Parser a) -> Value -> Parser a
withScientific' forall a. (Bounded a, Integral a) => Scientific -> Parser a
parseBoundedIntegralFromScientific

parseScientificText :: Text -> Parser Scientific
parseScientificText :: Text -> Parser Scientific
parseScientificText = forall r. (Scientific -> Text -> r) -> (String -> r) -> Text -> r
scanScientific
    (\Scientific
sci Text
rest -> if Text -> Bool
T.null Text
rest then forall (m :: * -> *) a. Monad m => a -> m a
return Scientific
sci else forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Expecting end-of-input, got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int -> Text -> Text
T.take Int
10 Text
rest))
    forall (m :: * -> *) a. MonadFail m => String -> m a
fail

parseIntegralText :: Integral a => String -> Text -> Parser a
parseIntegralText :: forall a. Integral a => String -> Text -> Parser a
parseIntegralText String
name Text
t =
    forall a. String -> Parser a -> Parser a
prependContext String
name forall a b. (a -> b) -> a -> b
$
            Text -> Parser Scientific
parseScientificText Text
t
        forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Scientific -> Parser Scientific
rejectLargeExponent
        forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. Integral a => Scientific -> Parser a
parseIntegralFromScientific
  where
    rejectLargeExponent :: Scientific -> Parser Scientific
    rejectLargeExponent :: Scientific -> Parser Scientific
rejectLargeExponent Scientific
s = forall a. (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific' forall (f :: * -> *) a. Applicative f => a -> f a
pure (Scientific -> Value
Number Scientific
s)

parseBoundedIntegralText :: (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText :: forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
name Text
t =
    forall a. String -> Parser a -> Parser a
prependContext String
name forall a b. (a -> b) -> a -> b
$
        Text -> Parser Scientific
parseScientificText Text
t forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. (Bounded a, Integral a) => Scientific -> Parser a
parseBoundedIntegralFromScientific

parseOptionalFieldWith :: (Value -> Parser (Maybe a))
                       -> Object -> Key -> Parser (Maybe a)
parseOptionalFieldWith :: forall a.
(Value -> Parser (Maybe a)) -> Object -> Key -> Parser (Maybe a)
parseOptionalFieldWith Value -> Parser (Maybe a)
pj Object
obj Key
key =
    case forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
key Object
obj of
     Maybe Value
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
     Just Value
v  -> Value -> Parser (Maybe a)
pj Value
v forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key

-------------------------------------------------------------------------------
-- Generics
-------------------------------------------------------------------------------

-- | Class of generic representation types that can be converted from JSON.
class GFromJSON arity f where
    -- | This method (applied to 'defaultOptions') is used as the
    -- default generic implementation of 'parseJSON' (if the @arity@ is 'Zero')
    -- or 'liftParseJSON' (if the @arity@ is 'One').
    gParseJSON :: Options -> FromArgs arity a -> Value -> Parser (f a)

-- | A 'FromArgs' value either stores nothing (for 'FromJSON') or it stores the
-- three function arguments that decode occurrences of the type parameter (for
-- 'FromJSON1').
data FromArgs arity a where
    NoFromArgs :: FromArgs Zero a
    From1Args  :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> FromArgs One a

-- | A configurable generic JSON decoder. This function applied to
-- 'defaultOptions' is used as the default for 'parseJSON' when the
-- type is an instance of 'Generic'.
genericParseJSON :: (Generic a, GFromJSON Zero (Rep a))
                 => Options -> Value -> Parser a
genericParseJSON :: forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
opts = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a x. Generic a => Rep a x -> a
to forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts forall a. FromArgs Zero a
NoFromArgs

-- | A configurable generic JSON decoder. This function applied to
-- 'defaultOptions' is used as the default for 'liftParseJSON' when the
-- type is an instance of 'Generic1'.
genericLiftParseJSON :: (Generic1 f, GFromJSON One (Rep1 f))
                     => Options -> Maybe a -> (Value -> Parser a) -> (Value -> Parser [a])
                     -> Value -> Parser (f a)
genericLiftParseJSON :: forall (f :: * -> *) a.
(Generic1 f, GFromJSON One (Rep1 f)) =>
Options
-> Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
genericLiftParseJSON Options
opts Maybe a
o Value -> Parser a
pj Value -> Parser [a]
pjl = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (a :: k). Generic1 f => Rep1 f a -> f a
to1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts (forall a.
Maybe a
-> (Value -> Parser a) -> (Value -> Parser [a]) -> FromArgs One a
From1Args Maybe a
o Value -> Parser a
pj Value -> Parser [a]
pjl)

-------------------------------------------------------------------------------
-- Class
-------------------------------------------------------------------------------

-- | A type that can be converted from JSON, with the possibility of
-- failure.
--
-- In many cases, you can get the compiler to generate parsing code
-- for you (see below).  To begin, let's cover writing an instance by
-- hand.
--
-- There are various reasons a conversion could fail.  For example, an
-- 'Object' could be missing a required key, an 'Array' could be of
-- the wrong size, or a value could be of an incompatible type.
--
-- The basic ways to signal a failed conversion are as follows:
--
-- * 'fail' yields a custom error message: it is the recommended way of
-- reporting a failure;
--
-- * 'Control.Applicative.empty' (or 'Control.Monad.mzero') is uninformative:
-- use it when the error is meant to be caught by some @('<|>')@;
--
-- * 'typeMismatch' can be used to report a failure when the encountered value
-- is not of the expected JSON type; 'unexpected' is an appropriate alternative
-- when more than one type may be expected, or to keep the expected type
-- implicit.
--
-- 'prependFailure' (or 'modifyFailure') add more information to a parser's
-- error messages.
--
-- An example type and instance using 'typeMismatch' and 'prependFailure':
--
-- @
-- \-- Allow ourselves to write 'Text' literals.
-- {-\# LANGUAGE OverloadedStrings #-}
--
-- data Coord = Coord { x :: Double, y :: Double }
--
-- instance 'FromJSON' Coord where
--     'parseJSON' ('Object' v) = Coord
--         '<$>' v '.:' \"x\"
--         '<*>' v '.:' \"y\"
--
--     \-- We do not expect a non-'Object' value here.
--     \-- We could use 'Control.Applicative.empty' to fail, but 'typeMismatch'
--     \-- gives a much more informative error message.
--     'parseJSON' invalid    =
--         'prependFailure' "parsing Coord failed, "
--             ('typeMismatch' \"Object\" invalid)
-- @
--
-- For this common case of only being concerned with a single
-- type of JSON value, the functions 'withObject', 'withScientific', etc.
-- are provided. Their use is to be preferred when possible, since
-- they are more terse. Using 'withObject', we can rewrite the above instance
-- (assuming the same language extension and data type) as:
--
-- @
-- instance 'FromJSON' Coord where
--     'parseJSON' = 'withObject' \"Coord\" $ \\v -> Coord
--         '<$>' v '.:' \"x\"
--         '<*>' v '.:' \"y\"
-- @
--
-- Instead of manually writing your 'FromJSON' instance, there are two options
-- to do it automatically:
--
-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
-- instance at compile time. The generated instance is optimized for your type
-- so it will probably be more efficient than the following option.
--
-- * The compiler can provide a default generic implementation for
-- 'parseJSON'.
--
-- To use the second, simply add a @deriving 'Generic'@ clause to your
-- datatype and declare a 'FromJSON' instance for your datatype without giving
-- a definition for 'parseJSON'.
--
-- For example, the previous example can be simplified to just:
--
-- @
-- {-\# LANGUAGE DeriveGeneric \#-}
--
-- import "GHC.Generics"
--
-- data Coord = Coord { x :: Double, y :: Double } deriving 'Generic'
--
-- instance 'FromJSON' Coord
-- @
--
-- or using the [DerivingVia extension](https://downloads.haskell.org/ghc/9.2.3/docs/html/users_guide/exts/deriving_via.html)
--
-- @
-- deriving via 'Generically' Coord instance 'FromJSON' Coord
-- @
--
-- The default implementation will be equivalent to
-- @parseJSON = 'genericParseJSON' 'defaultOptions'@; if you need different
-- options, you can customize the generic decoding by defining:
--
-- @
-- customOptions = 'defaultOptions'
--                 { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
--                 }
--
-- instance 'FromJSON' Coord where
--     'parseJSON' = 'genericParseJSON' customOptions
-- @
class FromJSON a where
    parseJSON :: Value -> Parser a

    default parseJSON :: (Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a
    parseJSON = forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions

    parseJSONList :: Value -> Parser [a]
    parseJSONList = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"[]" forall a b. (a -> b) -> a -> b
$ \Array
a ->
          forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (forall a. (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON forall a. FromJSON a => Value -> Parser a
parseJSON) [Int
0..]
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
V.toList
        forall a b. (a -> b) -> a -> b
$ Array
a

    -- | Default value for optional fields.
    -- Used by @('.:?=')@ operator, and Generics and TH deriving
    -- with @'allowOmittedFields' = True@ (default).
    --
    -- @since 2.2.0.0
    omittedField :: Maybe a
    omittedField = forall a. Maybe a
Nothing

-- | @since 2.1.0.0
instance (Generic a, GFromJSON Zero (Rep a)) => FromJSON (Generically a) where
    parseJSON :: Value -> Parser (Generically a)
parseJSON = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions :: Value -> Parser a)

-------------------------------------------------------------------------------
--  Classes and types for map keys
-------------------------------------------------------------------------------

-- | Read the docs for 'ToJSONKey' first. This class is a conversion
--   in the opposite direction. If you have a newtype wrapper around 'Text',
--   the recommended way to define instances is with generalized newtype deriving:
--
--   > newtype SomeId = SomeId { getSomeId :: Text }
--   >   deriving (Eq,Ord,Hashable,FromJSONKey)
--
--   If you have a sum of nullary constructors, you may use the generic
--   implementation:
--
-- @
-- data Color = Red | Green | Blue
--   deriving Generic
--
-- instance 'FromJSONKey' Color where
--   'fromJSONKey' = 'genericFromJSONKey' 'defaultJSONKeyOptions'
-- @
class FromJSONKey a where
    -- | Strategy for parsing the key of a map-like container.
    fromJSONKey :: FromJSONKeyFunction a
    default fromJSONKey :: FromJSON a => FromJSONKeyFunction a
    fromJSONKey = forall a. (Value -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyValue forall a. FromJSON a => Value -> Parser a
parseJSON

    -- | This is similar in spirit to the 'readList' method of 'Read'.
    --   It makes it possible to give 'String' keys special treatment
    --   without using @OverlappingInstances@. End users should always
    --   be able to use the default implementation of this method.
    fromJSONKeyList :: FromJSONKeyFunction [a]
    default fromJSONKeyList :: FromJSON a => FromJSONKeyFunction [a]
    fromJSONKeyList = forall a. (Value -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyValue forall a. FromJSON a => Value -> Parser a
parseJSON

-- | This type is related to 'ToJSONKeyFunction'. If 'FromJSONKeyValue' is used in the
--   'FromJSONKey' instance, then 'ToJSONKeyValue' should be used in the 'ToJSONKey'
--   instance. The other three data constructors for this type all correspond to
--   'ToJSONKeyText'. Strictly speaking, 'FromJSONKeyTextParser' is more powerful than
--   'FromJSONKeyText', which is in turn more powerful than 'FromJSONKeyCoerce'.
--   For performance reasons, these exist as three options instead of one.
data FromJSONKeyFunction a where
    FromJSONKeyCoerce :: Coercible Text a => FromJSONKeyFunction a
      -- ^ uses 'coerce', we expect that 'Hashable' and 'Ord' instance are compatible.
    FromJSONKeyText :: !(Text -> a) -> FromJSONKeyFunction a
      -- ^ conversion from 'Text' that always succeeds
    FromJSONKeyTextParser :: !(Text -> Parser a) -> FromJSONKeyFunction a
      -- ^ conversion from 'Text' that may fail
    FromJSONKeyValue :: !(Value -> Parser a) -> FromJSONKeyFunction a
      -- ^ conversion for non-textual keys

-- | Only law abiding up to interpretation
instance Functor FromJSONKeyFunction where
    fmap :: forall a b.
(a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
fmap a -> b
h FromJSONKeyFunction a
FromJSONKeyCoerce         = forall a. (Text -> a) -> FromJSONKeyFunction a
FromJSONKeyText (a -> b
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce)
    fmap a -> b
h (FromJSONKeyText Text -> a
f)       = forall a. (Text -> a) -> FromJSONKeyFunction a
FromJSONKeyText (a -> b
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> a
f)
    fmap a -> b
h (FromJSONKeyTextParser Text -> Parser a
f) = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Parser a
f)
    fmap a -> b
h (FromJSONKeyValue Value -> Parser a
f)      = forall a. (Value -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyValue (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
h forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser a
f)

-- | Construct 'FromJSONKeyFunction' for types coercible from 'Text'. This
-- conversion is still unsafe, as 'Hashable' and 'Eq' instances of @a@ should be
-- compatible with 'Text' i.e. hash values should be equal for wrapped values as well.
-- This property will always be maintained if the 'Hashable' and 'Eq' instances
-- are derived with generalized newtype deriving.
-- compatible with 'Text' i.e. hash values be equal for wrapped values as well.
--
-- On pre GHC 7.8 this is unconstrained function.
fromJSONKeyCoerce ::
    Coercible Text a =>
    FromJSONKeyFunction a
fromJSONKeyCoerce :: forall a. Coercible Text a => FromJSONKeyFunction a
fromJSONKeyCoerce = forall a. Coercible Text a => FromJSONKeyFunction a
FromJSONKeyCoerce

-- | Semantically the same as @coerceFromJSONKeyFunction = fmap coerce = coerce@.
--
-- See note on 'fromJSONKeyCoerce'.
coerceFromJSONKeyFunction ::
    Coercible a b =>
    FromJSONKeyFunction a -> FromJSONKeyFunction b
coerceFromJSONKeyFunction :: forall a b.
Coercible a b =>
FromJSONKeyFunction a -> FromJSONKeyFunction b
coerceFromJSONKeyFunction = coerce :: forall a b. Coercible a b => a -> b
coerce

{-# RULES
  "FromJSONKeyCoerce: fmap coerce" forall x .
                                   fmap coerce x = coerceFromJSONKeyFunction x
  #-}

-- | Same as 'fmap'. Provided for the consistency with 'ToJSONKeyFunction'.
mapFromJSONKeyFunction :: (a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
mapFromJSONKeyFunction :: forall a b.
(a -> b) -> FromJSONKeyFunction a -> FromJSONKeyFunction b
mapFromJSONKeyFunction = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

-- | 'fromJSONKey' for 'Generic' types.
-- These types must be sums of nullary constructors, whose names will be used
-- as keys for JSON objects.
--
-- See also 'genericToJSONKey'.
--
-- === __Example__
--
-- @
-- data Color = Red | Green | Blue
--   deriving 'Generic'
--
-- instance 'FromJSONKey' Color where
--   'fromJSONKey' = 'genericFromJSONKey' 'defaultJSONKeyOptions'
-- @
genericFromJSONKey :: forall a. (Generic a, GFromJSONKey (Rep a))
             => JSONKeyOptions
             -> FromJSONKeyFunction a
genericFromJSONKey :: forall a.
(Generic a, GFromJSONKey (Rep a)) =>
JSONKeyOptions -> FromJSONKeyFunction a
genericFromJSONKey JSONKeyOptions
opts = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
t ->
    case forall {k} (f :: k -> *) (a :: k).
SumFromString f =>
(String -> String) -> Text -> Maybe (f a)
parseSumFromString (JSONKeyOptions -> String -> String
keyModifier JSONKeyOptions
opts) Text
t of
        Maybe (Rep a Any)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
            String
"invalid key " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
t forall a. [a] -> [a] -> [a]
++ String
", expected one of " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [String]
cnames
        Just Rep a Any
k -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a x. Generic a => Rep a x -> a
to Rep a Any
k)
  where
    cnames :: [String]
cnames = forall (s :: * -> *) b. Tagged2 s b -> b
unTagged2 (forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a [t]
constructorTags (JSONKeyOptions -> String -> String
keyModifier JSONKeyOptions
opts) :: Tagged2 (Rep a) [String])

class    (ConstructorNames f, SumFromString f) => GFromJSONKey f where
instance (ConstructorNames f, SumFromString f) => GFromJSONKey f where

-------------------------------------------------------------------------------
-- Functions needed for documentation
-------------------------------------------------------------------------------

-- | Fail parsing due to a type mismatch, with a descriptive message.
--
-- The following wrappers should generally be preferred:
-- 'withObject', 'withArray', 'withText', 'withBool'.
--
-- ==== Error message example
--
-- > typeMismatch "Object" (String "oops")
-- > -- Error: "expected Object, but encountered String"
typeMismatch :: String -- ^ The name of the JSON type being parsed
                       -- (@\"Object\"@, @\"Array\"@, @\"String\"@, @\"Number\"@,
                       -- @\"Boolean\"@, or @\"Null\"@).
             -> Value  -- ^ The actual value encountered.
             -> Parser a
typeMismatch :: forall a. String -> Value -> Parser a
typeMismatch String
expected Value
actual =
    forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"expected " forall a. [a] -> [a] -> [a]
++ String
expected forall a. [a] -> [a] -> [a]
++ String
", but encountered " forall a. [a] -> [a] -> [a]
++ Value -> String
typeOf Value
actual

-- | Fail parsing due to a type mismatch, when the expected types are implicit.
--
-- ==== Error message example
--
-- > unexpected (String "oops")
-- > -- Error: "unexpected String"
unexpected :: Value -> Parser a
unexpected :: forall a. Value -> Parser a
unexpected Value
actual = forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unexpected " forall a. [a] -> [a] -> [a]
++ Value -> String
typeOf Value
actual

-- | JSON type of a value, name of the head constructor.
typeOf :: Value -> String
typeOf :: Value -> String
typeOf Value
v = case Value
v of
    Object Object
_ -> String
"Object"
    Array Array
_  -> String
"Array"
    String Text
_ -> String
"String"
    Number Scientific
_ -> String
"Number"
    Bool Bool
_   -> String
"Boolean"
    Value
Null     -> String
"Null"

-------------------------------------------------------------------------------
-- Liftings of FromJSON and ToJSON to unary and binary type constructors
-------------------------------------------------------------------------------

-- | Lifting of the 'FromJSON' class to unary type constructors.
--
-- Instead of manually writing your 'FromJSON1' instance, there are two options
-- to do it automatically:
--
-- * "Data.Aeson.TH" provides Template Haskell functions which will derive an
-- instance at compile time. The generated instance is optimized for your type
-- so it will probably be more efficient than the following option.
--
-- * The compiler can provide a default generic implementation for
-- 'liftParseJSON'.
--
-- To use the second, simply add a @deriving 'Generic1'@ clause to your
-- datatype and declare a 'FromJSON1' instance for your datatype without giving
-- a definition for 'liftParseJSON'.
--
-- For example:
--
-- @
-- {-\# LANGUAGE DeriveGeneric \#-}
--
-- import "GHC.Generics"
--
-- data Pair a b = Pair { pairFst :: a, pairSnd :: b } deriving 'Generic1'
--
-- instance 'FromJSON' a => 'FromJSON1' (Pair a)
-- @
--
-- or
--
-- @
-- deriving via 'Generically1' (Pair a) instance 'FromJSON1' (Pair a)
-- @
--
-- If the default implementation doesn't give exactly the results you want,
-- you can customize the generic decoding with only a tiny amount of
-- effort, using 'genericLiftParseJSON' with your preferred 'Options':
--
-- @
-- customOptions = 'defaultOptions'
--                 { 'fieldLabelModifier' = 'map' 'Data.Char.toUpper'
--                 }
--
-- instance 'FromJSON' a => 'FromJSON1' (Pair a) where
--     'liftParseJSON' = 'genericLiftParseJSON' customOptions
-- @
class FromJSON1 f where
    liftParseJSON :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a)

    default liftParseJSON :: (Generic1 f, GFromJSON One (Rep1 f))
                          => Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a)
    liftParseJSON = forall (f :: * -> *) a.
(Generic1 f, GFromJSON One (Rep1 f)) =>
Options
-> Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
genericLiftParseJSON Options
defaultOptions

    liftParseJSONList :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser [f a]
    liftParseJSONList Maybe a
o Value -> Parser a
f Value -> Parser [a]
g Value
v = forall a. (Value -> Parser a) -> Value -> Parser [a]
listParser (forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
liftParseJSON Maybe a
o Value -> Parser a
f Value -> Parser [a]
g) Value
v

    liftOmittedField :: Maybe a -> Maybe (f a)
    liftOmittedField Maybe a
_ = forall a. Maybe a
Nothing

-- | @since 2.1.0.0
instance (Generic1 f, GFromJSON One (Rep1 f)) => FromJSON1 (Generically1 f) where
    liftParseJSON :: forall a. Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (Generically1 f a)
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Generically1 f a)
liftParseJSON = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (f :: * -> *) a.
(Generic1 f, GFromJSON One (Rep1 f)) =>
Options
-> Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
genericLiftParseJSON Options
defaultOptions :: Maybe a -> (Value -> Parser a) -> (Value -> Parser [a]) -> Value -> Parser (f a))

-- | Lift the standard 'parseJSON' function through the type constructor.
parseJSON1 :: (FromJSON1 f, FromJSON a) => Value -> Parser (f a)
parseJSON1 :: forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1 = forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
liftParseJSON forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser [a]
parseJSONList
{-# INLINE parseJSON1 #-}

-- | @since 2.2.0.0
omittedField1 :: (FromJSON1 f, FromJSON a) => Maybe (f a)
omittedField1 :: forall (f :: * -> *) a. (FromJSON1 f, FromJSON a) => Maybe (f a)
omittedField1 = forall (f :: * -> *) a. FromJSON1 f => Maybe a -> Maybe (f a)
liftOmittedField forall a. FromJSON a => Maybe a
omittedField

-- | Lifting of the 'FromJSON' class to binary type constructors.
--
-- Instead of manually writing your 'FromJSON2' instance, "Data.Aeson.TH"
-- provides Template Haskell functions which will derive an instance at compile time.

-- The compiler cannot provide a default generic implementation for 'liftParseJSON2',
-- unlike 'parseJSON' and 'liftParseJSON'.
class FromJSON2 f where
    liftParseJSON2
        :: Maybe a
        -> (Value -> Parser a)
        -> (Value -> Parser [a])
        -> Maybe b
        -> (Value -> Parser b)
        -> (Value -> Parser [b])
        -> Value -> Parser (f a b)
    liftParseJSONList2
        :: Maybe a
        -> (Value -> Parser a)
        -> (Value -> Parser [a])
        -> Maybe b
        -> (Value -> Parser b)
        -> (Value -> Parser [b])
        -> Value -> Parser [f a b]
    liftParseJSONList2 Maybe a
oa Value -> Parser a
fa Value -> Parser [a]
ga Maybe b
ob Value -> Parser b
fb Value -> Parser [b]
gb = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"[]" forall a b. (a -> b) -> a -> b
$ \Array
vals ->
        forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Vector a -> [a]
V.toList (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
V.mapM (forall (f :: * -> * -> *) a b.
FromJSON2 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Maybe b
-> (Value -> Parser b)
-> (Value -> Parser [b])
-> Value
-> Parser (f a b)
liftParseJSON2 Maybe a
oa Value -> Parser a
fa Value -> Parser [a]
ga Maybe b
ob Value -> Parser b
fb Value -> Parser [b]
gb) Array
vals)

    liftOmittedField2 :: Maybe a -> Maybe b -> Maybe (f a b)
    liftOmittedField2 Maybe a
_ Maybe b
_ = forall a. Maybe a
Nothing

-- | Lift the standard 'parseJSON' function through the type constructor.
parseJSON2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Value -> Parser (f a b)
parseJSON2 :: forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Value -> Parser (f a b)
parseJSON2 = forall (f :: * -> * -> *) a b.
FromJSON2 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Maybe b
-> (Value -> Parser b)
-> (Value -> Parser [b])
-> Value
-> Parser (f a b)
liftParseJSON2 forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser [a]
parseJSONList forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser [a]
parseJSONList
{-# INLINE parseJSON2 #-}

-- | @since 2.2.0.0
omittedField2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Maybe (f a b)
omittedField2 :: forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Maybe (f a b)
omittedField2 = forall (f :: * -> * -> *) a b.
FromJSON2 f =>
Maybe a -> Maybe b -> Maybe (f a b)
liftOmittedField2 forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Maybe a
omittedField

-------------------------------------------------------------------------------
-- List functions
-------------------------------------------------------------------------------

-- | Helper function to use with 'liftParseJSON'. See 'Data.Aeson.ToJSON.listEncoding'.
listParser :: (Value -> Parser a) -> Value -> Parser [a]
listParser :: forall a. (Value -> Parser a) -> Value -> Parser [a]
listParser Value -> Parser a
f (Array Array
xs) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Vector a -> [a]
V.toList (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Vector a -> m (Vector b)
V.mapM Value -> Parser a
f Array
xs)
listParser Value -> Parser a
_ Value
v          = forall a. String -> Value -> Parser a
typeMismatch String
"Array" Value
v
{-# INLINE listParser #-}

-------------------------------------------------------------------------------
-- [] instances
-------------------------------------------------------------------------------

instance FromJSON1 [] where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser [a]
liftParseJSON Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
p' = Value -> Parser [a]
p'

instance (FromJSON a) => FromJSON [a] where
    parseJSON :: Value -> Parser [a]
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1

-------------------------------------------------------------------------------
-- Functions
-------------------------------------------------------------------------------

-- | Add context to a failure message, indicating the name of the structure
-- being parsed.
--
-- > prependContext "MyType" (fail "[error message]")
-- > -- Error: "parsing MyType failed, [error message]"
prependContext :: String -> Parser a -> Parser a
prependContext :: forall a. String -> Parser a -> Parser a
prependContext String
name = forall a. String -> Parser a -> Parser a
prependFailure (String
"parsing " forall a. [a] -> [a] -> [a]
++ String
name forall a. [a] -> [a] -> [a]
++ String
" failed, ")

-- | @'withObject' name f value@ applies @f@ to the 'Object' when @value@
-- is an 'Data.Aeson.Object' and fails otherwise.
--
-- ==== Error message example
--
-- > withObject "MyType" f (String "oops")
-- > -- Error: "parsing MyType failed, expected Object, but encountered String"
withObject :: String -> (Object -> Parser a) -> Value -> Parser a
withObject :: forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
_    Object -> Parser a
f (Object Object
obj) = Object -> Parser a
f Object
obj
withObject String
name Object -> Parser a
_ Value
v            = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"Object" Value
v)

-- | @'withText' name f value@ applies @f@ to the 'Text' when @value@ is a
-- 'Data.Aeson.String' and fails otherwise.
--
-- ==== Error message example
--
-- > withText "MyType" f Null
-- > -- Error: "parsing MyType failed, expected String, but encountered Null"
withText :: String -> (Text -> Parser a) -> Value -> Parser a
withText :: forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
_    Text -> Parser a
f (String Text
txt) = Text -> Parser a
f Text
txt
withText String
name Text -> Parser a
_ Value
v            = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"String" Value
v)

-- | @'withArray' expected f value@ applies @f@ to the 'Array' when @value@ is
-- an 'Data.Aeson.Array' and fails otherwise.
--
-- ==== Error message example
--
-- > withArray "MyType" f (String "oops")
-- > -- Error: "parsing MyType failed, expected Array, but encountered String"
withArray :: String -> (Array -> Parser a) -> Value -> Parser a
withArray :: forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
_    Array -> Parser a
f (Array Array
arr) = Array -> Parser a
f Array
arr
withArray String
name Array -> Parser a
_ Value
v           = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"Array" Value
v)

-- | @'withScientific' name f value@ applies @f@ to the 'Scientific' number
-- when @value@ is a 'Data.Aeson.Number' and fails using 'typeMismatch'
-- otherwise.
--
-- /Warning/: If you are converting from a scientific to an unbounded
-- type such as 'Integer' you may want to add a restriction on the
-- size of the exponent (see 'withBoundedScientific') to prevent
-- malicious input from filling up the memory of the target system.
--
-- ==== Error message example
--
-- > withScientific "MyType" f (String "oops")
-- > -- Error: "parsing MyType failed, expected Number, but encountered String"
withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific :: forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific String
_ Scientific -> Parser a
f (Number Scientific
scientific) = Scientific -> Parser a
f Scientific
scientific
withScientific String
name Scientific -> Parser a
_ Value
v = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"Number" Value
v)

-- | A variant of 'withScientific' which doesn't use 'prependContext', so that
-- such context can be added separately in a way that also applies when the
-- continuation @f :: Scientific -> Parser a@ fails.
--
-- /Warning/: If you are converting from a scientific to an unbounded
-- type such as 'Integer' you may want to add a restriction on the
-- size of the exponent (see 'withBoundedScientific') to prevent
-- malicious input from filling up the memory of the target system.
--
-- ==== Error message examples
--
-- > withScientific' f (String "oops")
-- > -- Error: "unexpected String"
-- >
-- > prependContext "MyType" (withScientific' f (String "oops"))
-- > -- Error: "parsing MyType failed, unexpected String"
withScientific' :: (Scientific -> Parser a) -> Value -> Parser a
withScientific' :: forall a. (Scientific -> Parser a) -> Value -> Parser a
withScientific' Scientific -> Parser a
f Value
v = case Value
v of
    Number Scientific
n -> Scientific -> Parser a
f Scientific
n
    Value
_ -> forall a. String -> Value -> Parser a
typeMismatch String
"Number" Value
v

-- | @'withBoundedScientific' name f value@ applies @f@ to the 'Scientific' number
-- when @value@ is a 'Number' with exponent less than or equal to 1024.
withBoundedScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific :: forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific String
name Scientific -> Parser a
f Value
v = forall a.
(Parser a -> Parser a)
-> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific_ (forall a. String -> Parser a -> Parser a
prependContext String
name) Scientific -> Parser a
f Value
v

-- | A variant of 'withBoundedScientific' which doesn't use 'prependContext',
-- so that such context can be added separately in a way that also applies
-- when the continuation @f :: Scientific -> Parser a@ fails.
withBoundedScientific' :: (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific' :: forall a. (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific' Scientific -> Parser a
f Value
v = forall a.
(Parser a -> Parser a)
-> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific_ forall a. a -> a
id Scientific -> Parser a
f Value
v

-- | A variant of 'withBoundedScientific_' parameterized by a function to apply
-- to the 'Parser' in case of failure.
withBoundedScientific_ :: (Parser a -> Parser a) -> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific_ :: forall a.
(Parser a -> Parser a)
-> (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific_ Parser a -> Parser a
whenFail Scientific -> Parser a
f (Number Scientific
scientific) =
    if Int
exp10 forall a. Ord a => a -> a -> Bool
> Int
1024
    then Parser a -> Parser a
whenFail (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
msg)
    else Scientific -> Parser a
f Scientific
scientific
  where
    exp10 :: Int
exp10 = Scientific -> Int
base10Exponent Scientific
scientific
    msg :: String
msg = String
"found a number with exponent " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
exp10 forall a. [a] -> [a] -> [a]
++ String
", but it must not be greater than 1024"
withBoundedScientific_ Parser a -> Parser a
whenFail Scientific -> Parser a
_ Value
v =
    Parser a -> Parser a
whenFail (forall a. String -> Value -> Parser a
typeMismatch String
"Number" Value
v)

-- | @'withBool' expected f value@ applies @f@ to the 'Bool' when @value@ is a
-- 'Boolean' and fails otherwise.
--
-- ==== Error message example
--
-- > withBool "MyType" f (String "oops")
-- > -- Error: "parsing MyType failed, expected Boolean, but encountered String"
withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
withBool :: forall a. String -> (Bool -> Parser a) -> Value -> Parser a
withBool String
_    Bool -> Parser a
f (Bool Bool
arr) = Bool -> Parser a
f Bool
arr
withBool String
name Bool -> Parser a
_ Value
v          = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"Boolean" Value
v)

-- | Decode a nested JSON-encoded string.
withEmbeddedJSON :: String -> (Value -> Parser a) -> Value -> Parser a
withEmbeddedJSON :: forall a. String -> (Value -> Parser a) -> Value -> Parser a
withEmbeddedJSON String
_ Value -> Parser a
innerParser (String Text
txt) =
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => String -> m a
fail Value -> Parser a
innerParser forall a b. (a -> b) -> a -> b
$ forall a. FromJSON a => ByteString -> Either String a
eitherDecode (ByteString -> ByteString
L.fromStrict forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
txt)
    where
        -- TODO: decode from strict text
        eitherDecode :: (FromJSON a) => L.ByteString -> Either String a
        eitherDecode :: forall a. FromJSON a => ByteString -> Either String a
eitherDecode ByteString
bs = forall e k a.
Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
unResult (forall k e. Tokens k e -> Result e k Value
toResultValue (ByteString -> Tokens ByteString String
lbsToTokens ByteString
bs)) forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ \Value
v ByteString
bs' -> case forall a. FromJSON a => Value -> IResult a
ifromJSON Value
v of
            ISuccess a
x
                | ByteString -> Bool
lbsSpace ByteString
bs' -> forall a b. b -> Either a b
Right a
x
                | Bool
otherwise    -> forall a b. a -> Either a b
Left String
"Trailing garbage"
            IError JSONPath
path String
msg  -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ JSONPath -> String -> String
formatError JSONPath
path String
msg

withEmbeddedJSON String
name Value -> Parser a
_ Value
v = forall a. String -> Parser a -> Parser a
prependContext String
name (forall a. String -> Value -> Parser a
typeMismatch String
"String" Value
v)

-- | Convert a value from JSON, failing if the types do not match.
fromJSON :: (FromJSON a) => Value -> Result a
fromJSON :: forall a. FromJSON a => Value -> Result a
fromJSON = forall a b. (a -> Parser b) -> a -> Result b
parse forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Convert a value from JSON, failing if the types do not match.
ifromJSON :: (FromJSON a) => Value -> IResult a
ifromJSON :: forall a. FromJSON a => Value -> IResult a
ifromJSON = forall a b. (a -> Parser b) -> a -> IResult b
iparse forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Retrieve the value associated with the given key of an 'Object'.
-- The result is 'empty' if the key is not present or the value cannot
-- be converted to the desired type.
--
-- This accessor is appropriate if the key and value /must/ be present
-- in an object for it to be valid.  If the key and value are
-- optional, use '.:?' instead.
(.:) :: (FromJSON a) => Object -> Key -> Parser a
.: :: forall a. FromJSON a => Object -> Key -> Parser a
(.:) = forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Retrieve the value associated with the given key of an 'Object'. The
-- result is 'Nothing' if the key is not present or if its value is 'Null',
-- or 'empty' if the value cannot be converted to the desired type.
--
-- This accessor is most useful if the key and value can be absent
-- from an object without affecting its validity.  If the key and
-- value are mandatory, use '.:' instead.
(.:?) :: (FromJSON a) => Object -> Key -> Parser (Maybe a)
.:? :: forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
(.:?) = forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Retrieve the value associated with the given key of an 'Object'.
-- The result is 'Nothing' if the key is not present or 'empty' if the
-- value cannot be converted to the desired type.
--
-- This differs from '.:?' by attempting to parse 'Null' the same as any
-- other JSON value, instead of interpreting it as 'Nothing'.
(.:!) :: (FromJSON a) => Object -> Key -> Parser (Maybe a)
.:! :: forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
(.:!) = forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe' forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Retrieve the value associated with the given key of an 'Object'.
-- If the key is not present and the 'omittedField' is @'Just' x@ for some @x@,
-- the result will be that @x@.
--
-- @since 2.2.0.0
(.:?=) :: (FromJSON a) => Object -> Key -> Parser a
.:?= :: forall a. FromJSON a => Object -> Key -> Parser a
(.:?=) = forall a.
Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Retrieve the value associated with the given key of an 'Object'.
-- If the key is not present or the field is @null@ and the 'omittedField' is @'Just' x@ for some @x@,
-- the result will be that @x@.
--
-- This differs from '.:?=' by attempting to parse 'Null' the same as any
-- other JSON value, instead of using 'omittedField' when it's 'Just'.
--
-- @since 2.2.0.0
(.:!=) :: (FromJSON a) => Object -> Key -> Parser a
.:!= :: forall a. FromJSON a => Object -> Key -> Parser a
(.:!=) = forall a.
Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit' forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON

-- | Function variant of '.:'.
parseField :: (FromJSON a) => Object -> Key -> Parser a
parseField :: forall a. FromJSON a => Object -> Key -> Parser a
parseField = forall a. FromJSON a => Object -> Key -> Parser a
(.:)

-- | Function variant of '.:?'.
parseFieldMaybe :: (FromJSON a) => Object -> Key -> Parser (Maybe a)
parseFieldMaybe :: forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
parseFieldMaybe = forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
(.:?)

-- | Function variant of '.:!'.
parseFieldMaybe' :: (FromJSON a) => Object -> Key -> Parser (Maybe a)
parseFieldMaybe' :: forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
parseFieldMaybe' = forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
(.:!)

-- | Function variant of '.:?='.
--
-- @since 2.2.0.0
parseFieldOmit :: (FromJSON a) => Object -> Key -> Parser a
parseFieldOmit :: forall a. FromJSON a => Object -> Key -> Parser a
parseFieldOmit = forall a. FromJSON a => Object -> Key -> Parser a
(.:?=)

-- | Function variant of '.:!='.
--
-- @since 2.2.0.0
parseFieldOmit' :: (FromJSON a) => Object -> Key -> Parser a
parseFieldOmit' :: forall a. FromJSON a => Object -> Key -> Parser a
parseFieldOmit' = forall a. FromJSON a => Object -> Key -> Parser a
(.:!=)

-- | Variant of '.:' with explicit parser function.
--
-- E.g. @'explicitParseField' 'parseJSON1' :: ('FromJSON1' f, 'FromJSON' a) -> 'Object' -> 'Text' -> 'Parser' (f a)@
explicitParseField :: (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField :: forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField Value -> Parser a
p Object
obj Key
key = case forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
key Object
obj of
    Maybe Value
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"key " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Key
key forall a. [a] -> [a] -> [a]
++ String
" not found"
    Just Value
v  -> Value -> Parser a
p Value
v forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key

-- | Variant of '.:?' with explicit parser function.
explicitParseFieldMaybe :: (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe :: forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe Value -> Parser a
p Object
obj Key
key = case forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
key Object
obj of
    Maybe Value
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
    Just Value
v  -> forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
liftParseJSON forall a. Maybe a
Nothing Value -> Parser a
p (forall a. (Value -> Parser a) -> Value -> Parser [a]
listParser Value -> Parser a
p) Value
v forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key -- listParser isn't used by maybe instance.

-- | Variant of '.:!' with explicit parser function.
explicitParseFieldMaybe' :: (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe' :: forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe' Value -> Parser a
p Object
obj Key
key = case forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
key Object
obj of
    Maybe Value
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
    Just Value
v  -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
p Value
v forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key

-- | Variant of '.:?=' with explicit arguments.
--
-- @since 2.2.0.0
explicitParseFieldOmit :: Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit :: forall a.
Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit Maybe a
Nothing    Value -> Parser a
p Object
obj Key
key = forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField Value -> Parser a
p Object
obj Key
key
explicitParseFieldOmit (Just a
def) Value -> Parser a
p Object
obj Key
key = forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe Value -> Parser a
p Object
obj Key
key forall a. Parser (Maybe a) -> a -> Parser a
.!= a
def

-- | Variant of '.:!=' with explicit arguments.
--
-- @since 2.2.0.0
explicitParseFieldOmit' :: Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit' :: forall a.
Maybe a -> (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseFieldOmit' Maybe a
Nothing    Value -> Parser a
p Object
obj Key
key = forall a. (Value -> Parser a) -> Object -> Key -> Parser a
explicitParseField Value -> Parser a
p Object
obj Key
key
explicitParseFieldOmit' (Just a
def) Value -> Parser a
p Object
obj Key
key = forall a. (Value -> Parser a) -> Object -> Key -> Parser (Maybe a)
explicitParseFieldMaybe' Value -> Parser a
p Object
obj Key
key forall a. Parser (Maybe a) -> a -> Parser a
.!= a
def

-- | Helper for use in combination with '.:?' to provide default
-- values for optional JSON object fields.
--
-- This combinator is most useful if the key and value can be absent
-- from an object without affecting its validity and we know a default
-- value to assign in that case.  If the key and value are mandatory,
-- use '.:' instead.
--
-- Example usage:
--
-- @ v1 <- o '.:?' \"opt_field_with_dfl\" .!= \"default_val\"
-- v2 <- o '.:'  \"mandatory_field\"
-- v3 <- o '.:?' \"opt_field2\"
-- @
(.!=) :: Parser (Maybe a) -> a -> Parser a
Parser (Maybe a)
pmval .!= :: forall a. Parser (Maybe a) -> a -> Parser a
.!= a
val = forall a. a -> Maybe a -> a
fromMaybe a
val forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Maybe a)
pmval

--------------------------------------------------------------------------------
-- Generic parseJSON
-------------------------------------------------------------------------------

instance GFromJSON arity V1 where
    -- Whereof we cannot format, thereof we cannot parse:
    gParseJSON :: forall a. Options -> FromArgs arity a -> Value -> Parser (V1 a)
gParseJSON Options
_ FromArgs arity a
_ Value
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Attempted to parse empty type"
    {-# INLINE gParseJSON #-}


instance {-# OVERLAPPABLE #-} (GFromJSON arity a) => GFromJSON arity (M1 i c a) where
    -- Meta-information, which is not handled elsewhere, is just added to the
    -- parsed value:
    gParseJSON :: forall a.
Options -> FromArgs arity a -> Value -> Parser (M1 i c a a)
gParseJSON Options
opts FromArgs arity a
fargs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts FromArgs arity a
fargs
    {-# INLINE gParseJSON #-}

-- Information for error messages

type TypeName = String
type ConName = String

-- | Add the name of the type being parsed to a parser's error messages.
contextType :: TypeName -> Parser a -> Parser a
contextType :: forall a. String -> Parser a -> Parser a
contextType = forall a. String -> Parser a -> Parser a
prependContext

-- | Add the tagKey that will be looked up while building an ADT
-- | Produce the error equivalent to
-- | Left "Error in $: parsing T failed, expected an object with keys "tag" and
-- | "contents", where "tag" i-- |s associated to one of ["Foo", "Bar"],
-- | The parser returned error was: could not find key "tag"
contextTag :: Key -> [String] -> Parser a -> Parser a
contextTag :: forall a. Key -> [String] -> Parser a -> Parser a
contextTag Key
tagKey [String]
cnames = forall a. String -> Parser a -> Parser a
prependFailure
  (String
"expected Object with key \"" forall a. [a] -> [a] -> [a]
++ Key -> String
Key.toString Key
tagKey forall a. [a] -> [a] -> [a]
++ String
"\"" forall a. [a] -> [a] -> [a]
++
  String
" containing one of " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [String]
cnames forall a. [a] -> [a] -> [a]
++ String
", ")

-- | Add the name of the constructor being parsed to a parser's error messages.
contextCons :: ConName -> TypeName -> Parser a -> Parser a
contextCons :: forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname = forall a. String -> Parser a -> Parser a
prependContext (String -> String -> String
showCons String
cname String
tname)

-- | Render a constructor as @\"MyType(MyConstructor)\"@.
showCons :: ConName -> TypeName -> String
showCons :: String -> String -> String
showCons String
cname String
tname = String
tname forall a. [a] -> [a] -> [a]
++ String
"(" forall a. [a] -> [a] -> [a]
++ String
cname forall a. [a] -> [a] -> [a]
++ String
")"

--------------------------------------------------------------------------------

-- Parsing single fields

instance (FromJSON a) => GFromJSON arity (K1 i a) where
    -- Constant values are decoded using their FromJSON instance:
    gParseJSON :: forall a. Options -> FromArgs arity a -> Value -> Parser (K1 i a a)
gParseJSON Options
_opts FromArgs arity a
_ = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i c (p :: k). c -> K1 i c p
K1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromJSON a => Value -> Parser a
parseJSON
    {-# INLINE gParseJSON #-}

instance GFromJSON One Par1 where
    -- Direct occurrences of the last type parameter are decoded with the
    -- function passed in as an argument:
    gParseJSON :: forall a. Options -> FromArgs One a -> Value -> Parser (Par1 a)
gParseJSON Options
_opts (From1Args Maybe a
_ Value -> Parser a
pj Value -> Parser [a]
_) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall p. p -> Par1 p
Par1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser a
pj
    {-# INLINE gParseJSON #-}

instance (FromJSON1 f) => GFromJSON One (Rec1 f) where
    -- Recursive occurrences of the last type parameter are decoded using their
    -- FromJSON1 instance:
    gParseJSON :: forall a. Options -> FromArgs One a -> Value -> Parser (Rec1 f a)
gParseJSON Options
_opts (From1Args Maybe a
o Value -> Parser a
pj Value -> Parser [a]
pjl) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (p :: k). f p -> Rec1 f p
Rec1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
liftParseJSON Maybe a
o Value -> Parser a
pj Value -> Parser [a]
pjl
    {-# INLINE gParseJSON #-}

instance (FromJSON1 f, GFromJSON One g) => GFromJSON One (f :.: g) where
    -- If an occurrence of the last type parameter is nested inside two
    -- composed types, it is decoded by using the outermost type's FromJSON1
    -- instance to generically decode the innermost type:
    --
    -- Note: the ommitedField is not passed here.
    -- This might be related for :.: associated the wrong way in Generics Rep.
    gParseJSON :: forall a.
Options -> FromArgs One a -> Value -> Parser ((:.:) f g a)
gParseJSON Options
opts FromArgs One a
fargs =
        let gpj :: Value -> Parser (g a)
gpj = forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts FromArgs One a
fargs
        in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (f a)
liftParseJSON forall a. Maybe a
Nothing Value -> Parser (g a)
gpj (forall a. (Value -> Parser a) -> Value -> Parser [a]
listParser Value -> Parser (g a)
gpj)
    {-# INLINE gParseJSON #-}

--------------------------------------------------------------------------------

instance (GFromJSON' arity a, Datatype d) => GFromJSON arity (D1 d a) where
    -- Meta-information, which is not handled elsewhere, is just added to the
    -- parsed value:
    gParseJSON :: forall a. Options -> FromArgs arity a -> Value -> Parser (D1 d a a)
gParseJSON Options
opts FromArgs arity a
fargs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON' arity f =>
(String :* (Options :* FromArgs arity a)) -> Value -> Parser (f a)
gParseJSON' (String
tname forall a b. a -> b -> a :* b
:* Options
opts forall a b. a -> b -> a :* b
:* FromArgs arity a
fargs)
      where
        tname :: String
tname = forall {k} (d :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Datatype d =>
t d f a -> String
moduleName M1 Any d Any Any
proxy forall a. [a] -> [a] -> [a]
++ String
"." forall a. [a] -> [a] -> [a]
++ forall {k} (d :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Datatype d =>
t d f a -> String
datatypeName M1 Any d Any Any
proxy
        proxy :: M1 Any d Any Any
proxy = forall a. HasCallStack => a
undefined :: M1 _i d _f _p
    {-# INLINE gParseJSON #-}

-- | 'GFromJSON', after unwrapping the 'D1' constructor, now carrying the data
-- type's name.
class GFromJSON' arity f where
    gParseJSON' :: TypeName :* Options :* FromArgs arity a
                -> Value
                -> Parser (f a)

-- | No constructors.
instance GFromJSON' arity V1 where
    gParseJSON' :: forall a.
(String :* (Options :* FromArgs arity a)) -> Value -> Parser (V1 a)
gParseJSON' String :* (Options :* FromArgs arity a)
_ Value
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Attempted to parse empty type"
    {-# INLINE gParseJSON' #-}

-- | Single constructor.
instance ( ConsFromJSON arity a
         , AllNullary         (C1 c a) allNullary
         , ParseSum     arity (C1 c a) allNullary
         , Constructor c
         ) => GFromJSON' arity (C1 c a) where
    -- The option 'tagSingleConstructors' determines whether to wrap
    -- a single-constructor type.
    gParseJSON' :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Parser (C1 c a a)
gParseJSON' p :: String :* (Options :* FromArgs arity a)
p@(String
_ :* Options
opts :* FromArgs arity a
_)
        | Options -> Bool
tagSingleConstructors Options
opts
            = (forall {k} (s :: k) b. Tagged s b -> b
unTagged :: Tagged allNullary (Parser (C1 c a p)) -> Parser (C1 c a p))
            forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} arity (f :: * -> *) (allNullary :: k) a.
ParseSum arity f allNullary =>
(String :* (Options :* FromArgs arity a))
-> Value -> Tagged allNullary (Parser (f a))
parseSum String :* (Options :* FromArgs arity a)
p
        | Bool
otherwise = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
ConsFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
consParseJSON (String
cname forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity a)
p)
      where
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
    {-# INLINE gParseJSON' #-}

-- | Multiple constructors.
instance ( AllNullary          (a :+: b) allNullary
         , ParseSum      arity (a :+: b) allNullary
         ) => GFromJSON' arity (a :+: b) where
    -- If all constructors of a sum datatype are nullary and the
    -- 'allNullaryToStringTag' option is set they are expected to be
    -- encoded as strings.  This distinction is made by 'parseSum':
    gParseJSON' :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Parser ((:+:) a b a)
gParseJSON' String :* (Options :* FromArgs arity a)
p =
        (forall {k} (s :: k) b. Tagged s b -> b
unTagged :: Tagged allNullary (Parser ((a :+: b) _d)) ->
                                        Parser ((a :+: b) _d))
                   forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} arity (f :: * -> *) (allNullary :: k) a.
ParseSum arity f allNullary =>
(String :* (Options :* FromArgs arity a))
-> Value -> Tagged allNullary (Parser (f a))
parseSum String :* (Options :* FromArgs arity a)
p
    {-# INLINE gParseJSON' #-}

--------------------------------------------------------------------------------

class ParseSum arity f allNullary where
    parseSum :: TypeName :* Options :* FromArgs arity a
             -> Value
             -> Tagged allNullary (Parser (f a))

instance ( ConstructorNames        f
         , SumFromString           f
         , FromPair          arity f
         , FromTaggedObject  arity f
         , FromUntaggedValue arity f
         ) => ParseSum       arity f True where
    parseSum :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Tagged True (Parser (f a))
parseSum p :: String :* (Options :* FromArgs arity a)
p@(String
tname :* Options
opts :* FromArgs arity a
_)
        | Options -> Bool
allNullaryToStringTag Options
opts = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a.
(SumFromString f, ConstructorNames f) =>
String -> Options -> Value -> Parser (f a)
parseAllNullarySum String
tname Options
opts
        | Bool
otherwise                  = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) c arity.
(FromPair arity f, FromTaggedObject arity f,
 FromUntaggedValue arity f, ConstructorNames f) =>
(String :* (Options :* FromArgs arity c)) -> Value -> Parser (f c)
parseNonAllNullarySum String :* (Options :* FromArgs arity a)
p
    {-# INLINE parseSum #-}

instance ( ConstructorNames        f
         , FromPair          arity f
         , FromTaggedObject  arity f
         , FromUntaggedValue arity f
         ) => ParseSum       arity f False where
    parseSum :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Tagged False (Parser (f a))
parseSum String :* (Options :* FromArgs arity a)
p = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) c arity.
(FromPair arity f, FromTaggedObject arity f,
 FromUntaggedValue arity f, ConstructorNames f) =>
(String :* (Options :* FromArgs arity c)) -> Value -> Parser (f c)
parseNonAllNullarySum String :* (Options :* FromArgs arity a)
p
    {-# INLINE parseSum #-}

--------------------------------------------------------------------------------

parseAllNullarySum :: (SumFromString f, ConstructorNames f)
                   => TypeName -> Options -> Value -> Parser (f a)
parseAllNullarySum :: forall (f :: * -> *) a.
(SumFromString f, ConstructorNames f) =>
String -> Options -> Value -> Parser (f a)
parseAllNullarySum String
tname Options
opts =
    forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
tname forall a b. (a -> b) -> a -> b
$ \Text
tag ->
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> Parser (f a)
badTag Text
tag) forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
            forall {k} (f :: k -> *) (a :: k).
SumFromString f =>
(String -> String) -> Text -> Maybe (f a)
parseSumFromString String -> String
modifier Text
tag
  where
    badTag :: Text -> Parser (f a)
badTag Text
tag = forall (f :: * -> *) a t.
ConstructorNames f =>
String -> (String -> t) -> ([t] -> String) -> Parser (f a)
failWithCTags String
tname String -> String
modifier forall a b. (a -> b) -> a -> b
$ \[String]
cnames ->
        String
"expected one of the tags " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [String]
cnames forall a. [a] -> [a] -> [a]
++
        String
", but found tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
tag
    modifier :: String -> String
modifier = Options -> String -> String
constructorTagModifier Options
opts

-- | Fail with an informative error message about a mismatched tag.
-- The error message is parameterized by the list of expected tags,
-- to be inferred from the result type of the parser.
failWithCTags
  :: forall f a t. ConstructorNames f
  => TypeName -> (String -> t) -> ([t] -> String) -> Parser (f a)
failWithCTags :: forall (f :: * -> *) a t.
ConstructorNames f =>
String -> (String -> t) -> ([t] -> String) -> Parser (f a)
failWithCTags String
tname String -> t
modifier [t] -> String
f =
    forall a. String -> Parser a -> Parser a
contextType String
tname forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ [t] -> String
f [t]
cnames
  where
    cnames :: [t]
cnames = forall (s :: * -> *) b. Tagged2 s b -> b
unTagged2 (forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a [t]
constructorTags String -> t
modifier :: Tagged2 f [t])

class SumFromString f where
    parseSumFromString :: (String -> String) -> Text -> Maybe (f a)

instance (SumFromString a, SumFromString b) => SumFromString (a :+: b) where
    parseSumFromString :: forall (a :: k). (String -> String) -> Text -> Maybe ((:+:) a b a)
parseSumFromString String -> String
opts Text
key = (forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (f :: k -> *) (a :: k).
SumFromString f =>
(String -> String) -> Text -> Maybe (f a)
parseSumFromString String -> String
opts Text
key) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
                                  (forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (f :: k -> *) (a :: k).
SumFromString f =>
(String -> String) -> Text -> Maybe (f a)
parseSumFromString String -> String
opts Text
key)
    {-# INLINE parseSumFromString #-}

instance (Constructor c) => SumFromString (C1 c U1) where
    parseSumFromString :: forall (a :: k). (String -> String) -> Text -> Maybe (C1 c U1 a)
parseSumFromString String -> String
modifier Text
key
        | Text
key forall a. Eq a => a -> a -> Bool
== Text
name = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall k (p :: k). U1 p
U1
        | Bool
otherwise   = forall a. Maybe a
Nothing
      where
        name :: Text
name = String -> Text
pack forall a b. (a -> b) -> a -> b
$ String -> String
modifier forall a b. (a -> b) -> a -> b
$ forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
    {-# INLINE parseSumFromString #-}

-- For genericFromJSONKey
instance SumFromString a => SumFromString (D1 d a) where
    parseSumFromString :: forall (a :: k). (String -> String) -> Text -> Maybe (D1 d a a)
parseSumFromString String -> String
modifier Text
key = forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (f :: k -> *) (a :: k).
SumFromString f =>
(String -> String) -> Text -> Maybe (f a)
parseSumFromString String -> String
modifier Text
key
    {-# INLINE parseSumFromString #-}

-- | List of all constructor tags.
constructorTags :: ConstructorNames a => (String -> t) -> Tagged2 a [t]
constructorTags :: forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a [t]
constructorTags String -> t
modifier =
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. DList a -> [a]
DList.toList (forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a (DList t)
constructorNames' String -> t
modifier)

-- | List of all constructor names of an ADT, after a given conversion
-- function. (Better inlining.)
class ConstructorNames a where
    constructorNames' :: (String -> t) -> Tagged2 a (DList.DList t)

instance (ConstructorNames a, ConstructorNames b) => ConstructorNames (a :+: b) where
    constructorNames' :: forall t. (String -> t) -> Tagged2 (a :+: b) (DList t)
constructorNames' = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 forall t.
Tagged2 a (DList t)
-> Tagged2 b (DList t) -> Tagged2 (a :+: b) (DList t)
append forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a (DList t)
constructorNames' forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a (DList t)
constructorNames'
      where
        append
          :: Tagged2 a (DList.DList t)
          -> Tagged2 b (DList.DList t)
          -> Tagged2 (a :+: b) (DList.DList t)
        append :: forall t.
Tagged2 a (DList t)
-> Tagged2 b (DList t) -> Tagged2 (a :+: b) (DList t)
append (Tagged2 DList t
xs) (Tagged2 DList t
ys) = forall (s :: * -> *) b. b -> Tagged2 s b
Tagged2 (forall a. DList a -> DList a -> DList a
DList.append DList t
xs DList t
ys)
    {-# INLINE constructorNames' #-}

instance Constructor c => ConstructorNames (C1 c a) where
    constructorNames' :: forall t. (String -> t) -> Tagged2 (C1 c a) (DList t)
constructorNames' String -> t
f = forall (s :: * -> *) b. b -> Tagged2 s b
Tagged2 (forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> t
f String
cname))
      where
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
    {-# INLINE constructorNames' #-}

-- For genericFromJSONKey
instance ConstructorNames a => ConstructorNames (D1 d a) where
    constructorNames' :: forall t. (String -> t) -> Tagged2 (D1 d a) (DList t)
constructorNames' = forall u. Tagged2 a u -> Tagged2 (D1 d a) u
retag forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a (DList t)
constructorNames'
      where
        retag :: Tagged2 a u -> Tagged2 (D1 d a) u
        retag :: forall u. Tagged2 a u -> Tagged2 (D1 d a) u
retag (Tagged2 u
x) = forall (s :: * -> *) b. b -> Tagged2 s b
Tagged2 u
x
    {-# INLINE constructorNames' #-}

--------------------------------------------------------------------------------
parseNonAllNullarySum :: forall f c arity.
                         ( FromPair          arity f
                         , FromTaggedObject  arity f
                         , FromUntaggedValue arity f
                         , ConstructorNames        f
                         ) => TypeName :* Options :* FromArgs arity c
                           -> Value -> Parser (f c)
parseNonAllNullarySum :: forall (f :: * -> *) c arity.
(FromPair arity f, FromTaggedObject arity f,
 FromUntaggedValue arity f, ConstructorNames f) =>
(String :* (Options :* FromArgs arity c)) -> Value -> Parser (f c)
parseNonAllNullarySum p :: String :* (Options :* FromArgs arity c)
p@(String
tname :* Options
opts :* FromArgs arity c
_) =
    case Options -> SumEncoding
sumEncoding Options
opts of
      TaggedObject{String
contentsFieldName :: SumEncoding -> String
tagFieldName :: SumEncoding -> String
contentsFieldName :: String
tagFieldName :: String
..} ->
          forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
tname forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
              Text
tag <- forall a. String -> Parser a -> Parser a
contextType String
tname forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Key -> [String] -> Parser a -> Parser a
contextTag Key
tagKey [String]
cnames_ forall a b. (a -> b) -> a -> b
$ Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
tagKey
              forall a. a -> Maybe a -> a
fromMaybe (Text -> Parser (f c)
badTag Text
tag forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
tagKey) forall a b. (a -> b) -> a -> b
$
                  forall arity (f :: * -> *) a.
FromTaggedObject arity f =>
(Text :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Maybe (Parser (f a))
parseFromTaggedObject (Text
tag forall a b. a -> b -> a :* b
:* String
contentsFieldName forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity c)
p) Object
obj
        where
          tagKey :: Key
tagKey = String -> Key
Key.fromString String
tagFieldName
          badTag :: Text -> Parser (f c)
badTag Text
tag = ([String] -> String) -> Parser (f c)
failWith_ forall a b. (a -> b) -> a -> b
$ \[String]
cnames ->
              String
"expected tag field to be one of " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [String]
cnames forall a. [a] -> [a] -> [a]
++
              String
", but found tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
tag
          cnames_ :: [String]
cnames_ = forall (s :: * -> *) b. Tagged2 s b -> b
unTagged2 (forall (a :: * -> *) t.
ConstructorNames a =>
(String -> t) -> Tagged2 a [t]
constructorTags (Options -> String -> String
constructorTagModifier Options
opts) :: Tagged2 f [String])

      SumEncoding
ObjectWithSingleField ->
          forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
tname forall a b. (a -> b) -> a -> b
$ \Object
obj -> case forall v. KeyMap v -> [(Key, v)]
KM.toList Object
obj of
              [(Key
tag, Value
v)] -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Key -> Parser (f c)
badTag Key
tag) (forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
tag) forall a b. (a -> b) -> a -> b
$
                  forall arity (f :: * -> *) a.
FromPair arity f =>
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser (f a))
parsePair (Key
tag forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity c)
p) Value
v
              [(Key, Value)]
_ -> forall a. String -> Parser a -> Parser a
contextType String
tname forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
                  String
"expected an Object with a single pair, but found " forall a. [a] -> [a] -> [a]
++
                  forall a. Show a => a -> String
show (forall v. KeyMap v -> Int
KM.size Object
obj) forall a. [a] -> [a] -> [a]
++ String
" pairs"
        where
          badTag :: Key -> Parser (f c)
badTag Key
tag = ([String] -> String) -> Parser (f c)
failWith_ forall a b. (a -> b) -> a -> b
$ \[String]
cnames ->
              String
"expected an Object with a single pair where the tag is one of " forall a. [a] -> [a] -> [a]
++
              forall a. Show a => a -> String
show [String]
cnames forall a. [a] -> [a] -> [a]
++ String
", but found tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Key
tag

      SumEncoding
TwoElemArray ->
          forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
tname forall a b. (a -> b) -> a -> b
$ \Array
arr -> case forall a. Vector a -> Int
V.length Array
arr of
              Int
2 | String Text
tag <- forall a. Vector a -> Int -> a
V.unsafeIndex Array
arr Int
0 ->
                  forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> Parser (f c)
badTag Text
tag forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
0) (forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
1) forall a b. (a -> b) -> a -> b
$
                      forall arity (f :: * -> *) a.
FromPair arity f =>
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser (f a))
parsePair (Text -> Key
Key.fromText Text
tag forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity c)
p) (forall a. Vector a -> Int -> a
V.unsafeIndex Array
arr Int
1)
                | Bool
otherwise ->
                  forall a. String -> Parser a -> Parser a
contextType String
tname forall a b. (a -> b) -> a -> b
$
                      forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"tag element is not a String" forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
0
              Int
len -> forall a. String -> Parser a -> Parser a
contextType String
tname forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
                  String
"expected a 2-element Array, but encountered an Array of length " forall a. [a] -> [a] -> [a]
++
                  forall a. Show a => a -> String
show Int
len
        where
          badTag :: Text -> Parser (f c)
badTag Text
tag = ([String] -> String) -> Parser (f c)
failWith_ forall a b. (a -> b) -> a -> b
$ \[String]
cnames ->
              String
"expected tag of the 2-element Array to be one of " forall a. [a] -> [a] -> [a]
++
              forall a. Show a => a -> String
show [String]
cnames forall a. [a] -> [a] -> [a]
++ String
", but found tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
tag

      SumEncoding
UntaggedValue -> forall arity (f :: * -> *) a.
FromUntaggedValue arity f =>
(String :* (Options :* FromArgs arity a)) -> Value -> Parser (f a)
parseUntaggedValue String :* (Options :* FromArgs arity c)
p
  where
    failWith_ :: ([String] -> String) -> Parser (f c)
failWith_ = forall (f :: * -> *) a t.
ConstructorNames f =>
String -> (String -> t) -> ([t] -> String) -> Parser (f a)
failWithCTags String
tname (Options -> String -> String
constructorTagModifier Options
opts)

--------------------------------------------------------------------------------

class FromTaggedObject arity f where
    -- The first two components of the parameter tuple are: the constructor tag
    -- to match against, and the contents field name.
    parseFromTaggedObject
        :: Text :* String :* TypeName :* Options :* FromArgs arity a
        -> Object
        -> Maybe (Parser (f a))

instance ( FromTaggedObject arity a, FromTaggedObject arity b) =>
    FromTaggedObject arity (a :+: b) where
        parseFromTaggedObject :: forall a.
(Text :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Maybe (Parser ((:+:) a b a))
parseFromTaggedObject Text :* (String :* (String :* (Options :* FromArgs arity a)))
p Object
obj =
            (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromTaggedObject arity f =>
(Text :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Maybe (Parser (f a))
parseFromTaggedObject Text :* (String :* (String :* (Options :* FromArgs arity a)))
p Object
obj) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
            (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromTaggedObject arity f =>
(Text :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Maybe (Parser (f a))
parseFromTaggedObject Text :* (String :* (String :* (Options :* FromArgs arity a)))
p Object
obj)
        {-# INLINE parseFromTaggedObject #-}

instance ( IsRecord                f isRecord
         , FromTaggedObject' arity f isRecord
         , Constructor c
         ) => FromTaggedObject arity (C1 c f) where
    parseFromTaggedObject :: forall a.
(Text :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Maybe (Parser (C1 c f a))
parseFromTaggedObject (Text
tag :* String
contentsFieldName :* p :: String :* (Options :* FromArgs arity a)
p@(String
_ :* Options
opts :* FromArgs arity a
_))
        | Text
tag forall a. Eq a => a -> a -> Bool
== Text
tag'
        = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            (forall {k} (s :: k) b. Tagged s b -> b
unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a)) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            forall {k} arity (f :: * -> *) (isRecord :: k) a.
FromTaggedObject' arity f isRecord =>
(String :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Tagged isRecord (Parser (f a))
parseFromTaggedObject' (String
contentsFieldName forall a b. a -> b -> a :* b
:* String
cname forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity a)
p)
        | Bool
otherwise = forall a b. a -> b -> a
const forall a. Maybe a
Nothing
      where
        tag' :: Text
tag' = String -> Text
pack forall a b. (a -> b) -> a -> b
$ Options -> String -> String
constructorTagModifier Options
opts String
cname
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
    {-# INLINE parseFromTaggedObject #-}

--------------------------------------------------------------------------------

class FromTaggedObject' arity f isRecord where
    -- The first component of the parameter tuple is the contents field name.
    parseFromTaggedObject'
        :: String :* ConName :* TypeName :* Options :* FromArgs arity a
        -> Object -> Tagged isRecord (Parser (f a))

instance (RecordFromJSON arity f, FieldNames f) => FromTaggedObject' arity f True where
    -- Records are unpacked in the tagged object
    parseFromTaggedObject' :: forall a.
(String :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Tagged True (Parser (f a))
parseFromTaggedObject' (String
_ :* String :* (String :* (Options :* FromArgs arity a))
p) = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
RecordFromJSON arity f =>
(Bool :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Parser (f a)
recordParseJSON (Bool
True forall a b. a -> b -> a :* b
:* String :* (String :* (Options :* FromArgs arity a))
p)
    {-# INLINE parseFromTaggedObject' #-}

instance (ConsFromJSON arity f) => FromTaggedObject' arity f False where
    -- Nonnullary nonrecords are encoded in the contents field
    parseFromTaggedObject' :: forall a.
(String :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Tagged False (Parser (f a))
parseFromTaggedObject' String :* (String :* (String :* (Options :* FromArgs arity a)))
p Object
obj = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall a b. (a -> b) -> a -> b
$ do
        Value
contents <- forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname (Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
key)
        forall arity (f :: * -> *) a.
ConsFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
consParseJSON String :* (String :* (Options :* FromArgs arity a))
p' Value
contents forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key
      where
        key :: Key
key = String -> Key
Key.fromString String
contentsFieldName
        String
contentsFieldName :* p' :: String :* (String :* (Options :* FromArgs arity a))
p'@(String
cname :* String
tname :* Options :* FromArgs arity a
_) = String :* (String :* (String :* (Options :* FromArgs arity a)))
p
    {-# INLINE parseFromTaggedObject' #-}

instance {-# OVERLAPPING #-} FromTaggedObject' arity U1 False where
    -- Nullary constructors don't need a contents field
    parseFromTaggedObject' :: forall a.
(String :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Tagged False (Parser (U1 a))
parseFromTaggedObject' String :* (String :* (String :* (Options :* FromArgs arity a)))
_ Object
_ = forall {k} (s :: k) b. b -> Tagged s b
Tagged (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall k (p :: k). U1 p
U1)
    {-# INLINE parseFromTaggedObject' #-}

--------------------------------------------------------------------------------

-- | Constructors need to be decoded differently depending on whether they're
-- a record or not. This distinction is made by 'ConsParseJSON'.
class ConsFromJSON arity f where
    consParseJSON
        :: ConName :* TypeName :* Options :* FromArgs arity a
        -> Value -> Parser (f a)

class ConsFromJSON' arity f isRecord where
    consParseJSON'
        :: ConName :* TypeName :* Options :* FromArgs arity a
        -> Value -> Tagged isRecord (Parser (f a))

instance ( IsRecord            f isRecord
         , ConsFromJSON' arity f isRecord
         ) => ConsFromJSON arity f where
    consParseJSON :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
consParseJSON String :* (String :* (Options :* FromArgs arity a))
p =
      (forall {k} (s :: k) b. Tagged s b -> b
unTagged :: Tagged isRecord (Parser (f a)) -> Parser (f a))
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} arity (f :: * -> *) (isRecord :: k) a.
ConsFromJSON' arity f isRecord =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged isRecord (Parser (f a))
consParseJSON' String :* (String :* (Options :* FromArgs arity a))
p
    {-# INLINE consParseJSON #-}

instance {-# OVERLAPPING #-}
         ( GFromJSON arity a, RecordFromJSON arity (S1 s a)
         ) => ConsFromJSON' arity (S1 s a) True where
    consParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged True (Parser (S1 s a a))
consParseJSON' p :: String :* (String :* (Options :* FromArgs arity a))
p@(String
cname :* String
tname :* Options
opts :* FromArgs arity a
fargs)
        | Options -> Bool
unwrapUnaryRecords Options
opts = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts FromArgs arity a
fargs
        | Bool
otherwise = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject (String -> String -> String
showCons String
cname String
tname) (forall arity (f :: * -> *) a.
RecordFromJSON arity f =>
(Bool :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Parser (f a)
recordParseJSON (Bool
False forall a b. a -> b -> a :* b
:* String :* (String :* (Options :* FromArgs arity a))
p))
    {-# INLINE consParseJSON' #-}

instance RecordFromJSON arity f => ConsFromJSON' arity f True where
    consParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged True (Parser (f a))
consParseJSON' p :: String :* (String :* (Options :* FromArgs arity a))
p@(String
cname :* String
tname :* Options :* FromArgs arity a
_) =
        forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject (String -> String -> String
showCons String
cname String
tname) (forall arity (f :: * -> *) a.
RecordFromJSON arity f =>
(Bool :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Parser (f a)
recordParseJSON (Bool
False forall a b. a -> b -> a :* b
:* String :* (String :* (Options :* FromArgs arity a))
p))
    {-# INLINE consParseJSON' #-}

instance {-# OVERLAPPING #-}
         ConsFromJSON' arity U1 False where
    -- Empty constructors are expected to be encoded as an empty array:
    consParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged False (Parser (U1 a))
consParseJSON' (String
cname :* String
tname :* Options :* FromArgs arity a
_) Value
v =
        forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname forall a b. (a -> b) -> a -> b
$ case Value
v of
            Array Array
a | forall a. Vector a -> Bool
V.null Array
a -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall k (p :: k). U1 p
U1
                    | Bool
otherwise -> forall {m :: * -> *} {a} {a}. MonadFail m => Vector a -> m a
fail_ Array
a
            Value
_ -> forall a. String -> Value -> Parser a
typeMismatch String
"Array" Value
v
      where
        fail_ :: Vector a -> m a
fail_ Vector a
a = forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
            String
"expected an empty Array, but encountered an Array of length " forall a. [a] -> [a] -> [a]
++
            forall a. Show a => a -> String
show (forall a. Vector a -> Int
V.length Vector a
a)
    {-# INLINE consParseJSON' #-}

instance {-# OVERLAPPING #-}
         GFromJSON arity f => ConsFromJSON' arity (S1 s f) False where
    consParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged False (Parser (S1 s f a))
consParseJSON' (String
_ :* String
_ :* Options
opts :* FromArgs arity a
fargs) =
        forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts FromArgs arity a
fargs
    {-# INLINE consParseJSON' #-}

instance (ProductFromJSON arity f, ProductSize f
         ) => ConsFromJSON' arity f False where
    consParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Tagged False (Parser (f a))
consParseJSON' String :* (String :* (Options :* FromArgs arity a))
p = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) arity a.
(ProductFromJSON arity f, ProductSize f) =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
productParseJSON0 String :* (String :* (Options :* FromArgs arity a))
p
    {-# INLINE consParseJSON' #-}

--------------------------------------------------------------------------------

class FieldNames f where
    fieldNames :: f a -> [String] -> [String]

instance (FieldNames a, FieldNames b) => FieldNames (a :*: b) where
    fieldNames :: forall (a :: k). (:*:) a b a -> [String] -> [String]
fieldNames (:*:) a b a
_ =
      forall {k} (f :: k -> *) (a :: k).
FieldNames f =>
f a -> [String] -> [String]
fieldNames (forall a. HasCallStack => a
undefined :: a x) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      forall {k} (f :: k -> *) (a :: k).
FieldNames f =>
f a -> [String] -> [String]
fieldNames (forall a. HasCallStack => a
undefined :: b y)
    {-# INLINE fieldNames #-}

instance (Selector s) => FieldNames (S1 s f) where
    fieldNames :: forall (a :: k). S1 s f a -> [String] -> [String]
fieldNames S1 s f a
_ = (forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall a. HasCallStack => a
undefined :: M1 _i s _f _p) forall a. a -> [a] -> [a]
:)
    {-# INLINE fieldNames #-}

class RecordFromJSON arity f where
    recordParseJSON
        :: Bool :* ConName :* TypeName :* Options :* FromArgs arity a
        -> Object -> Parser (f a)

instance ( FieldNames f
         , RecordFromJSON' arity f
         ) => RecordFromJSON arity f where
    recordParseJSON :: forall a.
(Bool :* (String :* (String :* (Options :* FromArgs arity a))))
-> Object -> Parser (f a)
recordParseJSON (Bool
fromTaggedSum :* p :: String :* (String :* (Options :* FromArgs arity a))
p@(String
cname :* String
tname :* Options
opts :* FromArgs arity a
_)) =
        \Object
obj -> Object -> Parser ()
checkUnknown Object
obj forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall arity (f :: * -> *) a.
RecordFromJSON' arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (f a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
p Object
obj
        where
            knownFields :: KM.KeyMap ()
            knownFields :: KeyMap ()
knownFields = forall v. [(Key, v)] -> KeyMap v
KM.fromList forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map ((,()) forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Key
Key.fromString) forall a b. (a -> b) -> a -> b
$
                [SumEncoding -> String
tagFieldName (Options -> SumEncoding
sumEncoding Options
opts) | Bool
fromTaggedSum] forall a. Semigroup a => a -> a -> a
<>
                (Options -> String -> String
fieldLabelModifier Options
opts forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (f :: k -> *) (a :: k).
FieldNames f =>
f a -> [String] -> [String]
fieldNames (forall a. HasCallStack => a
undefined :: f a) [])

            checkUnknown :: Object -> Parser ()
checkUnknown =
                if Bool -> Bool
not (Options -> Bool
rejectUnknownFields Options
opts)
                then \Object
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                else \Object
obj -> case forall v. KeyMap v -> [Key]
KM.keys (forall v v'. KeyMap v -> KeyMap v' -> KeyMap v
KM.difference Object
obj KeyMap ()
knownFields) of
                    [] -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                    [Key]
unknownFields -> forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname forall a b. (a -> b) -> a -> b
$
                        forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"unknown fields: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show [Key]
unknownFields)
    {-# INLINE recordParseJSON #-}

class RecordFromJSON' arity f where
    recordParseJSON'
        :: ConName :* TypeName :* Options :* FromArgs arity a
        -> Object -> Parser (f a)

instance ( RecordFromJSON' arity a
         , RecordFromJSON' arity b
         ) => RecordFromJSON' arity (a :*: b) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser ((:*:) a b a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
p Object
obj =
        forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
RecordFromJSON' arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (f a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
p Object
obj
              forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall arity (f :: * -> *) a.
RecordFromJSON' arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (f a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
p Object
obj
    {-# INLINE recordParseJSON' #-}

instance {-# OVERLAPPABLE #-}
         RecordFromJSON' arity f => RecordFromJSON' arity (M1 i s f) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (M1 i s f a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
args Object
obj = forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
RecordFromJSON' arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (f a)
recordParseJSON' String :* (String :* (Options :* FromArgs arity a))
args Object
obj
    {-# INLINE recordParseJSON' #-}

instance (Selector s, FromJSON a, Generic a, K1 i a ~ Rep a) =>
         RecordFromJSON' arity (S1 s (K1 i a)) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (S1 s (K1 i a) a)
recordParseJSON' args :: String :* (String :* (Options :* FromArgs arity a))
args@(String
_ :* String
_ :* Options
opts :* FromArgs arity a
_) Object
obj =
      forall (s :: Meta) arity a (f :: * -> *) i.
Selector s =>
Maybe (f a)
-> (Options -> FromArgs arity a -> Value -> Parser (f a))
-> (String :* (String :* (Options :* FromArgs arity a)))
-> Object
-> Parser (M1 i s f a)
recordParseJSONImpl (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Options -> Bool
allowOmittedFields Options
opts) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i c (p :: k). c -> K1 i c p
K1 forall a. FromJSON a => Maybe a
omittedField) forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON String :* (String :* (Options :* FromArgs arity a))
args Object
obj
    {-# INLINE recordParseJSON' #-}

instance {-# OVERLAPPING #-}
         (Selector s, FromJSON a) =>
         RecordFromJSON' arity (S1 s (Rec0 a)) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Object -> Parser (S1 s (Rec0 a) a)
recordParseJSON' args :: String :* (String :* (Options :* FromArgs arity a))
args@(String
_ :* String
_ :* Options
opts :* FromArgs arity a
_) Object
obj =
      forall (s :: Meta) arity a (f :: * -> *) i.
Selector s =>
Maybe (f a)
-> (Options -> FromArgs arity a -> Value -> Parser (f a))
-> (String :* (String :* (Options :* FromArgs arity a)))
-> Object
-> Parser (M1 i s f a)
recordParseJSONImpl (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Options -> Bool
allowOmittedFields Options
opts) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i c (p :: k). c -> K1 i c p
K1 forall a. FromJSON a => Maybe a
omittedField) forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON String :* (String :* (Options :* FromArgs arity a))
args Object
obj
    {-# INLINE recordParseJSON' #-}

instance {-# OVERLAPPING #-}
         (Selector s, GFromJSON One (Rec1 f), FromJSON1 f) =>
         RecordFromJSON' One (S1 s (Rec1 f)) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs One a)))
-> Object -> Parser (S1 s (Rec1 f) a)
recordParseJSON' args :: String :* (String :* (Options :* FromArgs One a))
args@(String
_ :* String
_ :* Options
opts :* From1Args Maybe a
o Value -> Parser a
_ Value -> Parser [a]
_) Object
obj =
      forall (s :: Meta) arity a (f :: * -> *) i.
Selector s =>
Maybe (f a)
-> (Options -> FromArgs arity a -> Value -> Parser (f a))
-> (String :* (String :* (Options :* FromArgs arity a)))
-> Object
-> Parser (M1 i s f a)
recordParseJSONImpl (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Options -> Bool
allowOmittedFields Options
opts) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (p :: k). f p -> Rec1 f p
Rec1 (forall (f :: * -> *) a. FromJSON1 f => Maybe a -> Maybe (f a)
liftOmittedField Maybe a
o)) forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON String :* (String :* (Options :* FromArgs One a))
args Object
obj
    {-# INLINE recordParseJSON' #-}

instance {-# OVERLAPPING #-}
         (Selector s, GFromJSON One Par1) =>
         RecordFromJSON' One (S1 s Par1) where
    recordParseJSON' :: forall a.
(String :* (String :* (Options :* FromArgs One a)))
-> Object -> Parser (S1 s Par1 a)
recordParseJSON' args :: String :* (String :* (Options :* FromArgs One a))
args@(String
_ :* String
_ :* Options
opts :* From1Args Maybe a
o Value -> Parser a
_ Value -> Parser [a]
_) Object
obj =
      forall (s :: Meta) arity a (f :: * -> *) i.
Selector s =>
Maybe (f a)
-> (Options -> FromArgs arity a -> Value -> Parser (f a))
-> (String :* (String :* (Options :* FromArgs arity a)))
-> Object
-> Parser (M1 i s f a)
recordParseJSONImpl (forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Options -> Bool
allowOmittedFields Options
opts) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall p. p -> Par1 p
Par1 Maybe a
o) forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON String :* (String :* (Options :* FromArgs One a))
args Object
obj
    {-# INLINE recordParseJSON' #-}


recordParseJSONImpl :: forall s arity a f i
                     . (Selector s)
                    => Maybe (f a)
                    -> (Options -> FromArgs arity a -> Value -> Parser (f a))
                    -> (ConName :* TypeName :* Options :* FromArgs arity a)
                    -> Object -> Parser (M1 i s f a)
recordParseJSONImpl :: forall (s :: Meta) arity a (f :: * -> *) i.
Selector s =>
Maybe (f a)
-> (Options -> FromArgs arity a -> Value -> Parser (f a))
-> (String :* (String :* (Options :* FromArgs arity a)))
-> Object
-> Parser (M1 i s f a)
recordParseJSONImpl Maybe (f a)
mdef Options -> FromArgs arity a -> Value -> Parser (f a)
parseVal (String
cname :* String
tname :* Options
opts :* FromArgs arity a
fargs) Object
obj =
  Maybe (M1 i s f a) -> Parser (M1 i s f a) -> Parser (M1 i s f a)
handleMissingKey (forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (f a)
mdef) forall a b. (a -> b) -> a -> b
$ do
    Value
fv <- forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname (Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
label)
    forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Options -> FromArgs arity a -> Value -> Parser (f a)
parseVal Options
opts FromArgs arity a
fargs Value
fv forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
label
  where
    handleMissingKey :: Maybe (M1 i s f a) -> Parser (M1 i s f a) -> Parser (M1 i s f a)
handleMissingKey Maybe (M1 i s f a)
Nothing Parser (M1 i s f a)
p = Parser (M1 i s f a)
p
    handleMissingKey (Just M1 i s f a
def) Parser (M1 i s f a)
p = if Key
label forall a. Key -> KeyMap a -> Bool
`KM.member` Object
obj then Parser (M1 i s f a)
p else forall (f :: * -> *) a. Applicative f => a -> f a
pure M1 i s f a
def

    label :: Key
label = String -> Key
Key.fromString forall a b. (a -> b) -> a -> b
$ Options -> String -> String
fieldLabelModifier Options
opts String
sname
    sname :: String
sname = forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName (forall a. HasCallStack => a
undefined :: M1 _i s _f _p)
{-# INLINE recordParseJSONImpl #-}

--------------------------------------------------------------------------------

productParseJSON0
    :: forall f arity a. (ProductFromJSON arity f, ProductSize f)
    => ConName :* TypeName :* Options :* FromArgs arity a
    -> Value -> Parser (f a)
    -- Products are expected to be encoded to an array. Here we check whether we
    -- got an array of the same size as the product, then parse each of the
    -- product's elements using productParseJSON:
productParseJSON0 :: forall (f :: * -> *) arity a.
(ProductFromJSON arity f, ProductSize f) =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
productParseJSON0 p :: String :* (String :* (Options :* FromArgs arity a))
p@(String
cname :* String
tname :* Options
_ :* FromArgs arity a
_) =
    forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray (String -> String -> String
showCons String
cname String
tname) forall a b. (a -> b) -> a -> b
$ \Array
arr ->
        let lenArray :: Int
lenArray = forall a. Vector a -> Int
V.length Array
arr
            lenProduct :: Int
lenProduct = (forall (s :: * -> *) b. Tagged2 s b -> b
unTagged2 :: Tagged2 f Int -> Int)
                         forall (f :: * -> *). ProductSize f => Tagged2 f Int
productSize in
        if Int
lenArray forall a. Eq a => a -> a -> Bool
== Int
lenProduct
        then forall arity (f :: * -> *) a.
ProductFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Array -> Int -> Int -> Parser (f a)
productParseJSON String :* (String :* (Options :* FromArgs arity a))
p Array
arr Int
0 Int
lenProduct
        else forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname forall a b. (a -> b) -> a -> b
$
             forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"expected an Array of length " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
lenProduct forall a. [a] -> [a] -> [a]
++
                    String
", but encountered an Array of length " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
lenArray

--

class ProductFromJSON arity f where
    productParseJSON :: ConName :* TypeName :* Options :* FromArgs arity a
                 -> Array -> Int -> Int
                 -> Parser (f a)

instance ( ProductFromJSON    arity a
         , ProductFromJSON    arity b
         ) => ProductFromJSON arity (a :*: b) where
    productParseJSON :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Array -> Int -> Int -> Parser ((:*:) a b a)
productParseJSON String :* (String :* (Options :* FromArgs arity a))
p Array
arr Int
ix Int
len =
        forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
(:*:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
ProductFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Array -> Int -> Int -> Parser (f a)
productParseJSON String :* (String :* (Options :* FromArgs arity a))
p Array
arr Int
ix  Int
lenL
              forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall arity (f :: * -> *) a.
ProductFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Array -> Int -> Int -> Parser (f a)
productParseJSON String :* (String :* (Options :* FromArgs arity a))
p Array
arr Int
ixR Int
lenR
        where
          lenL :: Int
lenL = Int
len forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1
          ixR :: Int
ixR  = Int
ix forall a. Num a => a -> a -> a
+ Int
lenL
          lenR :: Int
lenR = Int
len forall a. Num a => a -> a -> a
- Int
lenL

instance (GFromJSON arity a) => ProductFromJSON arity (S1 s a) where
    productParseJSON :: forall a.
(String :* (String :* (Options :* FromArgs arity a)))
-> Array -> Int -> Int -> Parser (S1 s a a)
productParseJSON (String
_ :* String
_ :* Options
opts :* FromArgs arity a
fargs) Array
arr Int
ix Int
_ =
        forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
GFromJSON arity f =>
Options -> FromArgs arity a -> Value -> Parser (f a)
gParseJSON Options
opts FromArgs arity a
fargs (forall a. Vector a -> Int -> a
V.unsafeIndex Array
arr Int
ix) forall a. Parser a -> JSONPathElement -> Parser a
<?> Int -> JSONPathElement
Index Int
ix
    {-# INLINE productParseJSON #-}

--------------------------------------------------------------------------------

class FromPair arity f where
    -- The first component of the parameter tuple is the tag to match.
    parsePair :: Key :* TypeName :* Options :* FromArgs arity a
              -> Value
              -> Maybe (Parser (f a))

instance ( FromPair arity a
         , FromPair arity b
         ) => FromPair arity (a :+: b) where
    parsePair :: forall a.
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser ((:+:) a b a))
parsePair Key :* (String :* (Options :* FromArgs arity a))
p Value
pair =
        (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromPair arity f =>
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser (f a))
parsePair Key :* (String :* (Options :* FromArgs arity a))
p Value
pair) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
        (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromPair arity f =>
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser (f a))
parsePair Key :* (String :* (Options :* FromArgs arity a))
p Value
pair)
    {-# INLINE parsePair #-}

instance ( Constructor c
         , ConsFromJSON arity a
         ) => FromPair arity (C1 c a) where
    parsePair :: forall a.
(Key :* (String :* (Options :* FromArgs arity a)))
-> Value -> Maybe (Parser (C1 c a a))
parsePair (Key
tag :* p :: String :* (Options :* FromArgs arity a)
p@(String
_ :* Options
opts :* FromArgs arity a
_)) Value
v
        | Key
tag forall a. Eq a => a -> a -> Bool
== Key
tag' = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
ConsFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
consParseJSON (String
cname forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity a)
p) Value
v
        | Bool
otherwise   = forall a. Maybe a
Nothing
      where
        tag' :: Key
tag' = String -> Key
Key.fromString forall a b. (a -> b) -> a -> b
$ Options -> String -> String
constructorTagModifier Options
opts String
cname
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _a _p)
    {-# INLINE parsePair #-}

--------------------------------------------------------------------------------

class FromUntaggedValue arity f where
    parseUntaggedValue :: TypeName :* Options :* FromArgs arity a
                       -> Value
                       -> Parser (f a)

instance
    ( FromUntaggedValue    arity a
    , FromUntaggedValue    arity b
    ) => FromUntaggedValue arity (a :+: b)
  where
    parseUntaggedValue :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Parser ((:+:) a b a)
parseUntaggedValue String :* (Options :* FromArgs arity a)
p Value
value =
        forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromUntaggedValue arity f =>
(String :* (Options :* FromArgs arity a)) -> Value -> Parser (f a)
parseUntaggedValue String :* (Options :* FromArgs arity a)
p Value
value forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
        forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall arity (f :: * -> *) a.
FromUntaggedValue arity f =>
(String :* (Options :* FromArgs arity a)) -> Value -> Parser (f a)
parseUntaggedValue String :* (Options :* FromArgs arity a)
p Value
value
    {-# INLINE parseUntaggedValue #-}

instance {-# OVERLAPPABLE #-}
    ( ConsFromJSON arity a
    , Constructor c
    ) => FromUntaggedValue arity (C1 c a)
  where
    parseUntaggedValue :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Parser (C1 c a a)
parseUntaggedValue String :* (Options :* FromArgs arity a)
p = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall arity (f :: * -> *) a.
ConsFromJSON arity f =>
(String :* (String :* (Options :* FromArgs arity a)))
-> Value -> Parser (f a)
consParseJSON (String
cname forall a b. a -> b -> a :* b
:* String :* (Options :* FromArgs arity a)
p)
      where
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
    {-# INLINE parseUntaggedValue #-}

instance {-# OVERLAPPING #-}
    ( Constructor c )
    => FromUntaggedValue arity (C1 c U1)
  where
    parseUntaggedValue :: forall a.
(String :* (Options :* FromArgs arity a))
-> Value -> Parser (C1 c U1 a)
parseUntaggedValue (String
tname :* Options
opts :* FromArgs arity a
_) Value
v =
        forall a. String -> String -> Parser a -> Parser a
contextCons String
cname String
tname forall a b. (a -> b) -> a -> b
$ case Value
v of
            String Text
tag
                | Text
tag forall a. Eq a => a -> a -> Bool
== Text
tag' -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 forall k (p :: k). U1 p
U1
                | Bool
otherwise -> Text -> Parser (C1 c U1 a)
fail_ Text
tag
            Value
_ -> forall a. String -> Value -> Parser a
typeMismatch String
"String" Value
v
      where
        tag' :: Text
tag' = String -> Text
pack forall a b. (a -> b) -> a -> b
$ Options -> String -> String
constructorTagModifier Options
opts String
cname
        cname :: String
cname = forall {k} (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName (forall a. HasCallStack => a
undefined :: M1 _i c _f _p)
        fail_ :: Text -> Parser (C1 c U1 a)
fail_ Text
tag = forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
          String
"expected tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
tag' forall a. [a] -> [a] -> [a]
++ String
", but found tag " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
tag
    {-# INLINE parseUntaggedValue #-}

-------------------------------------------------------------------------------
-- Instances
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- base
-------------------------------------------------------------------------------


instance FromJSON2 Const where
    liftParseJSON2 :: forall a b.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Maybe b
-> (Value -> Parser b)
-> (Value -> Parser [b])
-> Value
-> Parser (Const a b)
liftParseJSON2 Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ Maybe b
_ Value -> Parser b
_ Value -> Parser [b]
_ = coerce :: forall a b. Coercible a b => a -> b
coerce Value -> Parser a
p
    liftOmittedField2 :: forall a b. Maybe a -> Maybe b -> Maybe (Const a b)
liftOmittedField2 Maybe a
o Maybe b
_ = coerce :: forall a b. Coercible a b => a -> b
coerce Maybe a
o

instance FromJSON a => FromJSON1 (Const a) where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Const a a)
liftParseJSON Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
_ = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. FromJSON a => Value -> Parser a
parseJSON @a)
    liftOmittedField :: forall a. Maybe a -> Maybe (Const a a)
liftOmittedField Maybe a
_ = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. FromJSON a => Maybe a
omittedField @a)

instance FromJSON a => FromJSON (Const a b) where
    parseJSON :: Value -> Parser (Const a b)
parseJSON = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. FromJSON a => Value -> Parser a
parseJSON @a)
    omittedField :: Maybe (Const a b)
omittedField = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. FromJSON a => Maybe a
omittedField @a)

instance (FromJSON a, FromJSONKey a) => FromJSONKey (Const a b) where
    fromJSONKey :: FromJSONKeyFunction (Const a b)
fromJSONKey = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. FromJSONKey a => FromJSONKeyFunction a
fromJSONKey @a)


instance FromJSON1 Maybe where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Maybe a)
liftParseJSON Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
_ Value
Null = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
    liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ Value
a    = forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
p Value
a

    liftOmittedField :: forall a. Maybe a -> Maybe (Maybe a)
liftOmittedField Maybe a
_ = forall a. a -> Maybe a
Just forall a. Maybe a
Nothing

instance (FromJSON a) => FromJSON (Maybe a) where
    parseJSON :: Value -> Parser (Maybe a)
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1
    omittedField :: Maybe (Maybe a)
omittedField = forall (f :: * -> *) a. (FromJSON1 f, FromJSON a) => Maybe (f a)
omittedField1

instance FromJSON2 Either where
    liftParseJSON2 :: forall a b.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Maybe b
-> (Value -> Parser b)
-> (Value -> Parser [b])
-> Value
-> Parser (Either a b)
liftParseJSON2 Maybe a
_ Value -> Parser a
pA Value -> Parser [a]
_ Maybe b
_ Value -> Parser b
pB Value -> Parser [b]
_ (Object (forall v. KeyMap v -> [(Key, v)]
KM.toList -> [(Key
key, Value
value)]))
        | Key
key forall a. Eq a => a -> a -> Bool
== Key
left  = forall a b. a -> Either a b
Left  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
pA Value
value forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
left
        | Key
key forall a. Eq a => a -> a -> Bool
== Key
right = forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser b
pB Value
value forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
right
      where
        left, right :: Key
        left :: Key
left  = Key
"Left"
        right :: Key
right = Key
"Right"

    liftParseJSON2 Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
_ Maybe b
_ Value -> Parser b
_ Value -> Parser [b]
_ Value
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
        String
"expected an object with a single property " forall a. [a] -> [a] -> [a]
++
        String
"where the property key should be either " forall a. [a] -> [a] -> [a]
++
        String
"\"Left\" or \"Right\""

instance (FromJSON a) => FromJSON1 (Either a) where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Either a a)
liftParseJSON = forall (f :: * -> * -> *) a b.
FromJSON2 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Maybe b
-> (Value -> Parser b)
-> (Value -> Parser [b])
-> Value
-> Parser (f a b)
liftParseJSON2 forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser [a]
parseJSONList

instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
    parseJSON :: Value -> Parser (Either a b)
parseJSON = forall (f :: * -> * -> *) a b.
(FromJSON2 f, FromJSON a, FromJSON b) =>
Value -> Parser (f a b)
parseJSON2

instance FromJSON Void where
    parseJSON :: Value -> Parser Void
parseJSON Value
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot parse Void"

-- | @since 2.1.2.0
instance FromJSONKey Void where
    fromJSONKey :: FromJSONKeyFunction Void
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot parse Void"

instance FromJSON Bool where
    parseJSON :: Value -> Parser Bool
parseJSON (Bool Bool
b) = forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
b
    parseJSON Value
v = forall a. String -> Value -> Parser a
typeMismatch String
"Bool" Value
v

instance FromJSONKey Bool where
    fromJSONKey :: FromJSONKeyFunction Bool
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
t -> case Text
t of
        Text
"true"  -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
        Text
"false" -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
        Text
_       -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"cannot parse key " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
t forall a. [a] -> [a] -> [a]
++ String
" into Bool"

instance FromJSON Ordering where
  parseJSON :: Value -> Parser Ordering
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Ordering" forall a b. (a -> b) -> a -> b
$ \Text
s ->
    case Text
s of
      Text
"LT" -> forall (m :: * -> *) a. Monad m => a -> m a
return Ordering
LT
      Text
"EQ" -> forall (m :: * -> *) a. Monad m => a -> m a
return Ordering
EQ
      Text
"GT" -> forall (m :: * -> *) a. Monad m => a -> m a
return Ordering
GT
      Text
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"parsing Ordering failed, unexpected " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Text
s forall a. [a] -> [a] -> [a]
++
                  String
" (expected \"LT\", \"EQ\", or \"GT\")"

instance FromJSON () where
    parseJSON :: Value -> Parser ()
parseJSON Value
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    omittedField :: Maybe ()
omittedField = forall a. a -> Maybe a
Just ()

instance FromJSON Char where
    parseJSON :: Value -> Parser Char
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Char" Text -> Parser Char
parseChar

    parseJSONList :: Value -> Parser String
parseJSONList (String Text
s) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> String
T.unpack Text
s)
    parseJSONList Value
v = forall a. String -> Value -> Parser a
typeMismatch String
"String" Value
v

parseChar :: Text -> Parser Char
parseChar :: Text -> Parser Char
parseChar Text
t =
    if Text -> Int -> Ordering
T.compareLength Text
t Int
1 forall a. Eq a => a -> a -> Bool
== Ordering
EQ
      then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ HasCallStack => Text -> Char
T.head Text
t
      else forall a. String -> Parser a -> Parser a
prependContext String
"Char" forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expected a string of length 1"

instance FromJSON Double where
    parseJSON :: Value -> Parser Double
parseJSON = forall a. RealFloat a => String -> Value -> Parser a
parseRealFloat String
"Double"

instance FromJSONKey Double where
    fromJSONKey :: FromJSONKeyFunction Double
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
t -> case Text
t of
        Text
"NaN"   -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
0forall a. Fractional a => a -> a -> a
/Double
0)
        Text
"+inf"  -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Double
1forall a. Fractional a => a -> a -> a
/Double
0)
        Text
"-inf"  -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Num a => a -> a
negate Double
1forall a. Fractional a => a -> a -> a
/Double
0)
        Text
_       -> forall a. RealFloat a => Scientific -> a
Scientific.toRealFloat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Parser Scientific
parseScientificText Text
t

instance FromJSON Float where
    parseJSON :: Value -> Parser Float
parseJSON = forall a. RealFloat a => String -> Value -> Parser a
parseRealFloat String
"Float"

instance FromJSONKey Float where
    fromJSONKey :: FromJSONKeyFunction Float
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
t -> case Text
t of
        Text
"NaN"  -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Float
0forall a. Fractional a => a -> a -> a
/Float
0)
        Text
"+inf" -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Float
1forall a. Fractional a => a -> a -> a
/Float
0)
        Text
"-inf" -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Num a => a -> a
negate Float
1forall a. Fractional a => a -> a -> a
/Float
0)
        Text
_      -> forall a. RealFloat a => Scientific -> a
Scientific.toRealFloat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Parser Scientific
parseScientificText Text
t

instance (FromJSON a, Integral a) => FromJSON (Ratio a) where
    parseJSON :: Value -> Parser (Ratio a)
parseJSON (Number Scientific
x)
      | Int
exp10 forall a. Ord a => a -> a -> Bool
<= Int
1024
      , Int
exp10 forall a. Ord a => a -> a -> Bool
>= -Int
1024 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a b. (Real a, Fractional b) => a -> b
realToFrac Scientific
x
      | Bool
otherwise      = forall a. String -> Parser a -> Parser a
prependContext String
"Ratio" forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
msg
      where
        exp10 :: Int
exp10 = Scientific -> Int
base10Exponent Scientific
x
        msg :: String
msg = String
"found a number with exponent " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
exp10
           forall a. [a] -> [a] -> [a]
++ String
", but it must not be greater than 1024 or less than -1024"
    parseJSON Value
o = Value -> Parser (Ratio a)
objParser Value
o
      where
        objParser :: Value -> Parser (Ratio a)
objParser = forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Rational" forall a b. (a -> b) -> a -> b
$ \Object
obj -> do
            a
numerator <- Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"numerator"
            a
denominator <- Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"denominator"
            if a
denominator forall a. Eq a => a -> a -> Bool
== a
0
            then forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Ratio denominator was 0"
            else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ a
numerator forall a. Integral a => a -> a -> Ratio a
% a
denominator

-- | This instance includes a bounds check to prevent maliciously
-- large inputs to fill up the memory of the target system. You can
-- newtype 'Scientific' and provide your own instance using
-- 'withScientific' if you want to allow larger inputs.
instance HasResolution a => FromJSON (Fixed a) where
    parseJSON :: Value -> Parser (Fixed a)
parseJSON = forall a. String -> Parser a -> Parser a
prependContext String
"Fixed" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (Scientific -> Parser a) -> Value -> Parser a
withBoundedScientific' (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Real a, Fractional b) => a -> b
realToFrac)

instance FromJSON Int where
    parseJSON :: Value -> Parser Int
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Int"

instance FromJSONKey Int where
    fromJSONKey :: FromJSONKeyFunction Int
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Int"

-- | This instance includes a bounds check to prevent maliciously
-- large inputs to fill up the memory of the target system. You can
-- newtype 'Scientific' and provide your own instance using
-- 'withScientific' if you want to allow larger inputs.
instance FromJSON Integer where
    parseJSON :: Value -> Parser Integer
parseJSON = forall a. Integral a => String -> Value -> Parser a
parseIntegral String
"Integer"

instance FromJSONKey Integer where
    fromJSONKey :: FromJSONKeyFunction Integer
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. Integral a => String -> Text -> Parser a
parseIntegralText String
"Integer"

instance FromJSON Natural where
    parseJSON :: Value -> Parser Natural
parseJSON Value
value = do
        Integer
integer <- forall a. Integral a => String -> Value -> Parser a
parseIntegral String
"Natural" Value
value
        Integer -> Parser Natural
parseNatural Integer
integer

instance FromJSONKey Natural where
    fromJSONKey :: FromJSONKeyFunction Natural
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ \Text
text -> do
        Integer
integer <- forall a. Integral a => String -> Text -> Parser a
parseIntegralText String
"Natural" Text
text
        Integer -> Parser Natural
parseNatural Integer
integer

parseNatural :: Integer -> Parser Natural
parseNatural :: Integer -> Parser Natural
parseNatural Integer
integer =
    if Integer
integer forall a. Ord a => a -> a -> Bool
< Integer
0 then
        forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"parsing Natural failed, unexpected negative number " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Integer
integer
    else
        forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
integer

instance FromJSON Int8 where
    parseJSON :: Value -> Parser Int8
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Int8"

instance FromJSONKey Int8 where
    fromJSONKey :: FromJSONKeyFunction Int8
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Int8"

instance FromJSON Int16 where
    parseJSON :: Value -> Parser Int16
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Int16"

instance FromJSONKey Int16 where
    fromJSONKey :: FromJSONKeyFunction Int16
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Int16"

instance FromJSON Int32 where
    parseJSON :: Value -> Parser Int32
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Int32"

instance FromJSONKey Int32 where
    fromJSONKey :: FromJSONKeyFunction Int32
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Int32"

instance FromJSON Int64 where
    parseJSON :: Value -> Parser Int64
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Int64"

instance FromJSONKey Int64 where
    fromJSONKey :: FromJSONKeyFunction Int64
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Int64"

instance FromJSON Word where
    parseJSON :: Value -> Parser Word
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Word"

instance FromJSONKey Word where
    fromJSONKey :: FromJSONKeyFunction Word
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Word"

instance FromJSON Word8 where
    parseJSON :: Value -> Parser Word8
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Word8"

instance FromJSONKey Word8 where
    fromJSONKey :: FromJSONKeyFunction Word8
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Word8"

instance FromJSON Word16 where
    parseJSON :: Value -> Parser Word16
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Word16"

instance FromJSONKey Word16 where
    fromJSONKey :: FromJSONKeyFunction Word16
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Word16"

instance FromJSON Word32 where
    parseJSON :: Value -> Parser Word32
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Word32"

instance FromJSONKey Word32 where
    fromJSONKey :: FromJSONKeyFunction Word32
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Word32"

instance FromJSON Word64 where
    parseJSON :: Value -> Parser Word64
parseJSON = forall a. (Bounded a, Integral a) => String -> Value -> Parser a
parseBoundedIntegral String
"Word64"

instance FromJSONKey Word64 where
    fromJSONKey :: FromJSONKeyFunction Word64
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser forall a b. (a -> b) -> a -> b
$ forall a. (Bounded a, Integral a) => String -> Text -> Parser a
parseBoundedIntegralText String
"Word64"

instance FromJSON CTime where
    parseJSON :: Value -> Parser CTime
parseJSON = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int64 -> CTime
CTime forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromJSON a => Value -> Parser a
parseJSON

instance FromJSON Text where
    parseJSON :: Value -> Parser Text
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Text" forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance FromJSONKey Text where
    fromJSONKey :: FromJSONKeyFunction Text
fromJSONKey = forall a. Coercible Text a => FromJSONKeyFunction a
fromJSONKeyCoerce


instance FromJSON LT.Text where
    parseJSON :: Value -> Parser Text
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Lazy Text" forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
LT.fromStrict

instance FromJSONKey LT.Text where
    fromJSONKey :: FromJSONKeyFunction Text
fromJSONKey = forall a. (Text -> a) -> FromJSONKeyFunction a
FromJSONKeyText Text -> Text
LT.fromStrict

-- | @since 2.0.2.0
instance FromJSON ST.ShortText where
    parseJSON :: Value -> Parser ShortText
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"ShortText" forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ShortText
ST.fromText

-- | @since 2.0.2.0
instance FromJSONKey ST.ShortText where
    fromJSONKey :: FromJSONKeyFunction ShortText
fromJSONKey = forall a. (Text -> a) -> FromJSONKeyFunction a
FromJSONKeyText Text -> ShortText
ST.fromText


instance FromJSON Version where
    parseJSON :: Value -> Parser Version
parseJSON = forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Version" Text -> Parser Version
parseVersionText

instance FromJSONKey Version where
    fromJSONKey :: FromJSONKeyFunction Version
fromJSONKey = forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser Text -> Parser Version
parseVersionText

parseVersionText :: Text -> Parser Version
parseVersionText :: Text -> Parser Version
parseVersionText = forall {m :: * -> *} {a} {a}. MonadFail m => [(a, [a])] -> m a
go forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ReadP a -> ReadS a
readP_to_S ReadP Version
parseVersion forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack
  where
    go :: [(a, [a])] -> m a
go [(a
v,[])] = forall (m :: * -> *) a. Monad m => a -> m a
return a
v
    go ((a, [a])
_ : [(a, [a])]
xs) = [(a, [a])] -> m a
go [(a, [a])]
xs
    go [(a, [a])]
_        = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"parsing Version failed"

-------------------------------------------------------------------------------
-- semigroups NonEmpty
-------------------------------------------------------------------------------

instance FromJSON1 NonEmpty where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (NonEmpty a)
liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"NonEmpty" forall a b. (a -> b) -> a -> b
$
        (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {m :: * -> *} {a}. MonadFail m => [a] -> m (NonEmpty a)
ne) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
Tr.sequence forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (forall a. (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON Value -> Parser a
p) [Int
0..] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
V.toList
      where
        ne :: [a] -> m (NonEmpty a)
ne []     = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"parsing NonEmpty failed, unexpected empty list"
        ne (a
x:[a]
xs) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
x forall a. a -> [a] -> NonEmpty a
:| [a]
xs)

instance (FromJSON a) => FromJSON (NonEmpty a) where
    parseJSON :: Value -> Parser (NonEmpty a)
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1

-------------------------------------------------------------------------------
-- scientific
-------------------------------------------------------------------------------

instance FromJSON Scientific where
    parseJSON :: Value -> Parser Scientific
parseJSON = forall a. String -> (Scientific -> Parser a) -> Value -> Parser a
withScientific String
"Scientific" forall (f :: * -> *) a. Applicative f => a -> f a
pure

-------------------------------------------------------------------------------
-- DList
-------------------------------------------------------------------------------

instance FromJSON1 DList.DList where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (DList a)
liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"DList" forall a b. (a -> b) -> a -> b
$
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> DList a
DList.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
Tr.sequence forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (forall a. (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON Value -> Parser a
p) [Int
0..] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
V.toList

instance (FromJSON a) => FromJSON (DList.DList a) where
    parseJSON :: Value -> Parser (DList a)
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1

-- | @since 1.5.3.0
instance FromJSON1 DNE.DNonEmpty where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (DNonEmpty a)
liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ = forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"DNonEmpty" forall a b. (a -> b) -> a -> b
$
        (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {m :: * -> *} {a}. MonadFail m => [a] -> m (DNonEmpty a)
ne) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
Tr.sequence forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (forall a. (Value -> Parser a) -> Int -> Value -> Parser a
parseIndexedJSON Value -> Parser a
p) [Int
0..] forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
V.toList
      where
        ne :: [a] -> m (DNonEmpty a)
ne []     = forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"parsing DNonEmpty failed, unexpected empty list"
        ne (a
x:[a]
xs) = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. NonEmpty a -> DNonEmpty a
DNE.fromNonEmpty (a
x forall a. a -> [a] -> NonEmpty a
:| [a]
xs))

-- | @since 1.5.3.0
instance (FromJSON a) => FromJSON (DNE.DNonEmpty a) where
    parseJSON :: Value -> Parser (DNonEmpty a)
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1

-------------------------------------------------------------------------------
-- OneTuple
-------------------------------------------------------------------------------

-- | @since 2.0.2.0
instance FromJSON1 Solo where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Solo a)
liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ Value
a = forall a. a -> Solo a
Solo forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser a
p Value
a
    liftParseJSONList :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser [Solo a]
liftParseJSONList Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
p Value
a = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Solo a
Solo forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser [a]
p Value
a

-- | @since 2.0.2.0
instance (FromJSON a) => FromJSON (Solo a) where
    parseJSON :: Value -> Parser (Solo a)
parseJSON = forall (f :: * -> *) a.
(FromJSON1 f, FromJSON a) =>
Value -> Parser (f a)
parseJSON1
    parseJSONList :: Value -> Parser [Solo a]
parseJSONList = forall (f :: * -> *) a.
FromJSON1 f =>
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser [f a]
liftParseJSONList forall a. FromJSON a => Maybe a
omittedField forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser [a]
parseJSONList

-- | @since 2.0.2.0
instance (FromJSONKey a) => FromJSONKey (Solo a) where
    fromJSONKey :: FromJSONKeyFunction (Solo a)
fromJSONKey     = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Solo a
Solo forall a. FromJSONKey a => FromJSONKeyFunction a
fromJSONKey
    fromJSONKeyList :: FromJSONKeyFunction [Solo a]
fromJSONKeyList = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (a -> b) -> [a] -> [b]
map forall a. a -> Solo a
Solo) forall a. FromJSONKey a => FromJSONKeyFunction [a]
fromJSONKeyList

-------------------------------------------------------------------------------
-- transformers - Functors
-------------------------------------------------------------------------------

instance FromJSON1 Identity where
    liftParseJSON :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser (Identity a)
liftParseJSON Maybe a
_ Value -> Parser a
p Value -> Parser [a]
_ Value
a = coerce :: forall a b. Coercible a b => a -> b
coerce (Value -> Parser a
p Value
a)

    liftParseJSONList :: forall a.
Maybe a
-> (Value -> Parser a)
-> (Value -> Parser [a])
-> Value
-> Parser [Identity a]
liftParseJSONList Maybe a
_ Value -> Parser a
_ Value -> Parser [a]
p Value
a = coerce :: forall a b. Coercible a b => a -> b
coerce (Value -> Parser [a]
p Value
a)

    liftOmittedField :: forall a. Maybe a -> Maybe (Identity a)
liftOmittedField = coerce :: forall a b. Coercible a b => a -> b
coerce

instance (FromJSON a) => FromJSON (Identity a) where