    {-# LANGUAGE RankNTypes          #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    -- | Convertion to and from @aeson@ 'A.Value'.
    --
    module Data.Aeson.Decoding (
        decode,
        eitherDecode,
        throwDecode,
        decodeStrict,
        eitherDecodeStrict,
        throwDecodeStrict,
        decodeStrictText,
        eitherDecodeStrictText,
        throwDecodeStrictText,
        toEitherValue,
        unescapeText,
    ) where

    import           Control.Monad.Catch                 (MonadThrow (..))
    import           Data.Aeson.Types.Internal           (AesonException (..), formatError)

    import qualified Data.Aeson.Types                    as A
    import qualified Data.ByteString                     as BS
    import qualified Data.ByteString.Lazy                as LBS
    import qualified Data.Text                           as T

    import           Data.Aeson.Decoding.ByteString
    import           Data.Aeson.Decoding.ByteString.Lazy
    import           Data.Aeson.Decoding.Text
    import           Data.Aeson.Decoding.Conversion
    import           Data.Aeson.Internal.Unescape        (unescapeText)

    -------------------------------------------------------------------------------
    -- Decoding: strict bytestring
    -------------------------------------------------------------------------------

    -- | Efficiently deserialize a JSON value from a strict 'B.ByteString'.
    -- If this fails due to incomplete or invalid input, 'Nothing' is
    -- returned.
    decodeStrict :: (A.FromJSON a) => BS.ByteString -> Maybe a
    decodeStrict :: forall a. FromJSON a => ByteString -> Maybe a
    decodeStrict ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    bsToTokens ByteString
    bs)) (\String
    _ -> Maybe a
    forall a. Maybe a
    Nothing) ((Value -> ByteString -> Maybe a) -> Maybe a)
    -> (Value -> ByteString -> Maybe a) -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    bsSpace ByteString
    bs' -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x
            | Bool
    otherwise   -> Maybe a
    forall a. Maybe a
    Nothing
        A.IError JSONPath
    _ String
    _      -> Maybe a
    forall a. Maybe a
    Nothing

    -- | Like 'decodeStrict' but returns an error message when decoding fails.
    eitherDecodeStrict :: (A.FromJSON a) => BS.ByteString -> Either String a
    eitherDecodeStrict :: forall a. FromJSON a => ByteString -> Either String a
    eitherDecodeStrict ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    bsToTokens ByteString
    bs)) String -> Either String a
    forall a b. a -> Either a b
    Left ((Value -> ByteString -> Either String a) -> Either String a)
    -> (Value -> ByteString -> Either String a) -> Either String a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    bsSpace ByteString
    bs' -> a -> Either String a
    forall a b. b -> Either a b
    Right a
    x
            | Bool
    otherwise   -> String -> Either String a
    forall a b. a -> Either a b
    Left String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg -> String -> Either String a
    forall a b. a -> Either a b
    Left (String -> Either String a) -> String -> Either String a
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg

    -- | Like 'decodeStrict' but throws an 'AesonException' when decoding fails.
    throwDecodeStrict :: forall a m. (A.FromJSON a, MonadThrow m) => BS.ByteString -> m a
    throwDecodeStrict :: forall a (m :: * -> *).
    (FromJSON a, MonadThrow m) =>
    ByteString -> m a
    throwDecodeStrict ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    bsToTokens ByteString
    bs)) (AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a)
    -> (String -> AesonException) -> String -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> AesonException
    AesonException) ((Value -> ByteString -> m a) -> m a)
    -> (Value -> ByteString -> m a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    bsSpace ByteString
    bs' -> a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x
            | Bool
    otherwise   -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException (String -> AesonException) -> String -> AesonException
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg

    -------------------------------------------------------------------------------
    -- Decoding: lazy bytestring
    -------------------------------------------------------------------------------

    -- | Efficiently deserialize a JSON value from a lazy 'L.ByteString'.
    -- If this fails due to incomplete or invalid input, 'Nothing' is
    -- returned.
    decode :: (A.FromJSON a) => LBS.ByteString -> Maybe a
    decode :: forall a. FromJSON a => ByteString -> Maybe a
    decode ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    lbsToTokens ByteString
    bs)) (\String
    _ -> Maybe a
    forall a. Maybe a
    Nothing) ((Value -> ByteString -> Maybe a) -> Maybe a)
    -> (Value -> ByteString -> Maybe a) -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    lbsSpace ByteString
    bs' -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x
            | Bool
    otherwise    -> Maybe a
    forall a. Maybe a
    Nothing
        A.IError JSONPath
    _ String
    _       -> Maybe a
    forall a. Maybe a
    Nothing

    -- | Like 'decode' but returns an error message when decoding fails.
    eitherDecode :: (A.FromJSON a) => LBS.ByteString -> Either String a
    eitherDecode :: forall a. FromJSON a => ByteString -> Either String a
    eitherDecode ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    lbsToTokens ByteString
    bs)) String -> Either String a
    forall a b. a -> Either a b
    Left ((Value -> ByteString -> Either String a) -> Either String a)
    -> (Value -> ByteString -> Either String a) -> Either String a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    lbsSpace ByteString
    bs' -> a -> Either String a
    forall a b. b -> Either a b
    Right a
    x
            | Bool
    otherwise    -> String -> Either String a
    forall a b. a -> Either a b
    Left String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg  -> String -> Either String a
    forall a b. a -> Either a b
    Left (String -> Either String a) -> String -> Either String a
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg

    -- | Like 'decode' but throws an 'AesonException' when decoding fails.
    --
    -- 'throwDecode' is in @aeson@ since 2.1.2.0, but this variant is added later.
    throwDecode :: forall a m. (A.FromJSON a, MonadThrow m) => LBS.ByteString -> m a
    throwDecode :: forall a (m :: * -> *).
    (FromJSON a, MonadThrow m) =>
    ByteString -> m a
    throwDecode ByteString
    bs = Result String ByteString Value
    -> forall r. (String -> r) -> (Value -> ByteString -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens ByteString String -> Result String ByteString Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (ByteString -> Tokens ByteString String
    lbsToTokens ByteString
    bs)) (AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a)
    -> (String -> AesonException) -> String -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> AesonException
    AesonException) ((Value -> ByteString -> m a) -> m a)
    -> (Value -> ByteString -> m a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v ByteString
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | ByteString -> Bool
    lbsSpace ByteString
    bs'  -> a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x
            | Bool
    otherwise    -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg  -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException (String -> AesonException) -> String -> AesonException
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg

    -------------------------------------------------------------------------------
    -- Decoding: strict text
    -------------------------------------------------------------------------------

    -- | Efficiently deserialize a JSON value from a strict 'T.Text'.
    -- If this fails due to incomplete or invalid input, 'Nothing' is
    -- returned.
    --
    -- @since 2.2.1.0
    decodeStrictText :: (A.FromJSON a) => T.Text -> Maybe a
    decodeStrictText :: forall a. FromJSON a => Text -> Maybe a
    decodeStrictText Text
    bs = Result String Text Value
    -> forall r. (String -> r) -> (Value -> Text -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens Text String -> Result String Text Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (Text -> Tokens Text String
    textToTokens Text
    bs)) (\String
    _ -> Maybe a
    forall a. Maybe a
    Nothing) ((Value -> Text -> Maybe a) -> Maybe a)
    -> (Value -> Text -> Maybe a) -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v Text
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | Text -> Bool
    textSpace Text
    bs' -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x
            | Bool
    otherwise     -> Maybe a
    forall a. Maybe a
    Nothing
        A.IError JSONPath
    _ String
    _        -> Maybe a
    forall a. Maybe a
    Nothing

    -- | Like 'decodeStrictText' but returns an error message when decoding fails.
    --
    -- @since 2.2.1.0
    eitherDecodeStrictText :: (A.FromJSON a) => T.Text -> Either String a
    eitherDecodeStrictText :: forall a. FromJSON a => Text -> Either String a
    eitherDecodeStrictText Text
    bs = Result String Text Value
    -> forall r. (String -> r) -> (Value -> Text -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens Text String -> Result String Text Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (Text -> Tokens Text String
    textToTokens Text
    bs)) String -> Either String a
    forall a b. a -> Either a b
    Left ((Value -> Text -> Either String a) -> Either String a)
    -> (Value -> Text -> Either String a) -> Either String a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v Text
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | Text -> Bool
    textSpace Text
    bs' -> a -> Either String a
    forall a b. b -> Either a b
    Right a
    x
            | Bool
    otherwise     -> String -> Either String a
    forall a b. a -> Either a b
    Left String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg   -> String -> Either String a
    forall a b. a -> Either a b
    Left (String -> Either String a) -> String -> Either String a
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg

    -- | Like 'decodeStrictText' but throws an 'AesonException' when decoding fails.
    --
    -- @since 2.2.1.0
    throwDecodeStrictText :: forall a m. (A.FromJSON a, MonadThrow m) => T.Text -> m a
    throwDecodeStrictText :: forall a (m :: * -> *). (FromJSON a, MonadThrow m) => Text -> m a
    throwDecodeStrictText Text
    bs = Result String Text Value
    -> forall r. (String -> r) -> (Value -> Text -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens Text String -> Result String Text Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue (Text -> Tokens Text String
    textToTokens Text
    bs)) (AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a)
    -> (String -> AesonException) -> String -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> AesonException
    AesonException) ((Value -> Text -> m a) -> m a) -> (Value -> Text -> m a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \Value
    v Text
    bs' -> case Value -> IResult a
    forall a. FromJSON a => Value -> IResult a
    A.ifromJSON Value
    v of
        A.ISuccess a
    x
            | Text -> Bool
    textSpace Text
    bs' -> a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    x
            | Bool
    otherwise     -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException String
    "Trailing garbage"
        A.IError JSONPath
    path String
    msg   -> AesonException -> m a
    forall e a. (HasCallStack, Exception e) => e -> m a
    forall (m :: * -> *) e a.
    (MonadThrow m, HasCallStack, Exception e) =>
    e -> m a
    throwM (AesonException -> m a) -> AesonException -> m a
    forall a b. (a -> b) -> a -> b
    $ String -> AesonException
    AesonException (String -> AesonException) -> String -> AesonException
    forall a b. (a -> b) -> a -> b
    $ JSONPath -> String -> String
    formatError JSONPath
    path String
    msg