    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE RankNTypes   #-}
    module Data.Aeson.Decoding.Conversion (
        bsSpace,
        lbsSpace,
        textSpace,
        ltextSpace,
        toEitherValue,
        toResultValue,
        Result (..),
    ) where

    import           Data.Aeson.Key             (Key)
    import           Data.Scientific            (Scientific)

    import qualified Data.Aeson.KeyMap          as KM
    import qualified Data.Aeson.Types.Internal  as A
    import qualified Data.ByteString            as B
    import qualified Data.ByteString.Lazy       as L
    import qualified Data.Vector                as V
    import qualified Data.Text as T
    import qualified Data.Text.Lazy as LT

    import           Data.Aeson.Decoding.Tokens

    bsSpace :: B.ByteString -> Bool
    bsSpace :: ByteString -> Bool
    bsSpace = (Word8 -> Bool) -> ByteString -> Bool
    B.all (\Word8
    w -> Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x20 Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x0a Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x0d Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x09)

    lbsSpace :: L.ByteString -> Bool
    lbsSpace :: ByteString -> Bool
    lbsSpace = (Word8 -> Bool) -> ByteString -> Bool
    L.all (\Word8
    w -> Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x20 Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x0a Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x0d Bool -> Bool -> Bool
    || Word8
    w Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word8
    0x09)

    textSpace :: T.Text -> Bool
    textSpace :: Text -> Bool
    textSpace = (Char -> Bool) -> Text -> Bool
    T.all (\Char
    c -> Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    ' ' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\r' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\n' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\t')

    ltextSpace :: LT.Text -> Bool
    ltextSpace :: Text -> Bool
    ltextSpace = (Char -> Bool) -> Text -> Bool
    LT.all (\Char
    c -> Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    ' ' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\r' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\n' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\t')

    -- | Convert 'Tokens' to 'A.Value'.
    --
    -- The resulting value will be in normal form if its forced.
    -- In other words, there shouldn't be thunks inside.
    --
    toEitherValue
        :: Tokens k e             -- ^ tokens
        -> Either e (A.Value, k)  -- ^ either token error or value and leftover.
    toEitherValue :: forall k e. Tokens k e -> Either e (Value, k)
    toEitherValue Tokens k e
    t = Result e k Value -> forall r. (e -> r) -> (Value -> k -> r) -> r
    forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult (Tokens k e -> Result e k Value
    forall k e. Tokens k e -> Result e k Value
    toResultValue Tokens k e
    t) e -> Either e (Value, k)
    forall a b. a -> Either a b
    Left ((Value -> k -> Either e (Value, k)) -> Either e (Value, k))
    -> (Value -> k -> Either e (Value, k)) -> Either e (Value, k)
    forall a b. (a -> b) -> a -> b
    $ \Value
    v k
    k -> (Value, k) -> Either e (Value, k)
    forall a b. b -> Either a b
    Right (Value
    v, k
    k)

    toResultValue
        :: Tokens k e           -- ^ tokens
        -> Result e k A.Value   -- ^ either token error or value and leftover.
    toResultValue :: forall k e. Tokens k e -> Result e k Value
    toResultValue Tokens k e
    t0 = (forall r. (e -> r) -> (Value -> k -> r) -> r) -> Result e k Value
    forall e k a.
    (forall r. (e -> r) -> (a -> k -> r) -> r) -> Result e k a
    Result (Tokens k e -> (e -> r) -> (Value -> k -> r) -> r
    forall k e r. Tokens k e -> (e -> r) -> (Value -> k -> r) -> r
    convert Tokens k e
    t0)

    convert :: Tokens k e -> (e -> r) -> (A.Value -> k -> r) -> r
    convert :: forall k e r. Tokens k e -> (e -> r) -> (Value -> k -> r) -> r
    convert (TkLit Lit
    l k
    k)        e -> r
    _ Value -> k -> r
    f = Value -> k -> r
    f (Lit -> Value
    lit Lit
    l) k
    k where
        lit :: Lit -> A.Value
        lit :: Lit -> Value
    lit Lit
    LitNull  = Value
    A.Null
        lit Lit
    LitTrue  = Bool -> Value
    A.Bool Bool
    True
        lit Lit
    LitFalse = Bool -> Value
    A.Bool Bool
    False
    convert (TkText Text
    t k
    k)       e -> r
    _ Value -> k -> r
    f = Value -> k -> r
    f (Text -> Value
    A.String Text
    t) k
    k
    convert (TkNumber Number
    n k
    k)     e -> r
    _ Value -> k -> r
    f = Value -> k -> r
    f (Scientific -> Value
    A.Number (Number -> Scientific
    num Number
    n)) k
    k where
        num :: Number -> Scientific
        num :: Number -> Scientific
    num (NumInteger Integer
    m)    = Integer -> Scientific
    forall a. Num a => Integer -> a
    fromInteger Integer
    m
        num (NumDecimal Scientific
    s)    = Scientific
    s
        num (NumScientific Scientific
    s) = Scientific
    s
    convert (TkArrayOpen TkArray k e
    arr)  e -> r
    g Value -> k -> r
    f = TkArray k e -> (e -> r) -> (Array -> k -> r) -> r
    forall k e r. TkArray k e -> (e -> r) -> (Array -> k -> r) -> r
    convertA TkArray k e
    arr e -> r
    g ((Array -> k -> r) -> r) -> (Array -> k -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ \Array
    xs k
    k -> Value -> k -> r
    f (Array -> Value
    A.Array Array
    xs) k
    k
    convert (TkRecordOpen TkRecord k e
    rec) e -> r
    g Value -> k -> r
    f = TkRecord k e -> (e -> r) -> (Object -> k -> r) -> r
    forall k e r. TkRecord k e -> (e -> r) -> (Object -> k -> r) -> r
    convertR TkRecord k e
    rec e -> r
    g ((Object -> k -> r) -> r) -> (Object -> k -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ \Object
    xs k
    k -> Value -> k -> r
    f (Object -> Value
    A.Object Object
    xs) k
    k
    convert (TkErr e
    e)          e -> r
    g Value -> k -> r
    _ = e -> r
    g e
    e

    convertA :: TkArray k e -> (e -> r) -> (A.Array -> k -> r) -> r
    convertA :: forall k e r. TkArray k e -> (e -> r) -> (Array -> k -> r) -> r
    convertA TkArray k e
    tka e -> r
    err Array -> k -> r
    kont = Int
    -> ([Value] -> [Value])
    -> TkArray k e
    -> (e -> r)
    -> (Int -> [Value] -> k -> r)
    -> r
    forall k e r.
    Int
    -> ([Value] -> [Value])
    -> TkArray k e
    -> (e -> r)
    -> (Int -> [Value] -> k -> r)
    -> r
    goA Int
    0 [Value] -> [Value]
    forall a. a -> a
    id TkArray k e
    tka e -> r
    err ((Int -> [Value] -> k -> r) -> r)
    -> (Int -> [Value] -> k -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ \Int
    n [Value]
    xs -> Array -> k -> r
    kont (Int -> [Value] -> Array
    forall a. Int -> [a] -> Vector a
    V.fromListN Int
    n [Value]
    xs) where
        goA :: Int                           -- size accumulator
            -> ([A.Value] -> [A.Value])      -- dlist accumulator
            -> TkArray k e                   -- array tokens
            -> (e -> r)                      -- error continuation
            -> (Int -> [A.Value] -> k -> r)  -- success continuation
            -> r
        goA :: forall k e r.
    Int
    -> ([Value] -> [Value])
    -> TkArray k e
    -> (e -> r)
    -> (Int -> [Value] -> k -> r)
    -> r
    goA !Int
    n ![Value] -> [Value]
    acc (TkItem Tokens (TkArray k e) e
    toks)  e -> r
    g Int -> [Value] -> k -> r
    f = Tokens (TkArray k e) e
    -> (e -> r) -> (Value -> TkArray k e -> r) -> r
    forall k e r. Tokens k e -> (e -> r) -> (Value -> k -> r) -> r
    convert Tokens (TkArray k e) e
    toks e -> r
    g ((Value -> TkArray k e -> r) -> r)
    -> (Value -> TkArray k e -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ \ !Value
    v TkArray k e
    k -> Int
    -> ([Value] -> [Value])
    -> TkArray k e
    -> (e -> r)
    -> (Int -> [Value] -> k -> r)
    -> r
    forall k e r.
    Int
    -> ([Value] -> [Value])
    -> TkArray k e
    -> (e -> r)
    -> (Int -> [Value] -> k -> r)
    -> r
    goA (Int -> Int
    forall a. Enum a => a -> a
    succ Int
    n) ([Value] -> [Value]
    acc ([Value] -> [Value]) -> ([Value] -> [Value]) -> [Value] -> [Value]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Value
    v Value -> [Value] -> [Value]
    forall a. a -> [a] -> [a]
    :)) TkArray k e
    k e -> r
    g Int -> [Value] -> k -> r
    f
        goA !Int
    n ![Value] -> [Value]
    acc (TkArrayEnd k
    k) e -> r
    _ Int -> [Value] -> k -> r
    f = Int -> [Value] -> k -> r
    f Int
    n ([Value] -> [Value]
    acc []) k
    k
        goA !Int
    _ ![Value] -> [Value]
    _   (TkArrayErr e
    e) e -> r
    g Int -> [Value] -> k -> r
    _ = e -> r
    g e
    e

    convertR :: TkRecord k e -> (e -> r) -> (A.Object -> k -> r) -> r
    convertR :: forall k e r. TkRecord k e -> (e -> r) -> (Object -> k -> r) -> r
    convertR TkRecord k e
    tkr e -> r
    err Object -> k -> r
    kont = [(Key, Value)]
    -> TkRecord k e -> (e -> r) -> ([(Key, Value)] -> k -> r) -> r
    forall k e r.
    [(Key, Value)]
    -> TkRecord k e -> (e -> r) -> ([(Key, Value)] -> k -> r) -> r
    goR [] TkRecord k e
    tkr e -> r
    err (([(Key, Value)] -> k -> r) -> r)
    -> ([(Key, Value)] -> k -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ Object -> k -> r
    kont (Object -> k -> r)
    -> ([(Key, Value)] -> Object) -> [(Key, Value)] -> k -> r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [(Key, Value)] -> Object
    forall v. [(Key, v)] -> KeyMap v
    KM.fromList where
        -- we accumulate keys in reverse order
        -- then the first duplicate key in objects wins (as KM.fromList picks last).
        goR :: [(Key, A.Value)]
            -> TkRecord k e
            -> (e -> r)
            -> ([(Key, A.Value)] -> k -> r)
            -> r
        -- here we don't stricly need bang on !v as KM is a Strict (in values) map.
        -- but we force the value sooner.
        goR :: forall k e r.
    [(Key, Value)]
    -> TkRecord k e -> (e -> r) -> ([(Key, Value)] -> k -> r) -> r
    goR ![(Key, Value)]
    acc (TkPair Key
    t Tokens (TkRecord k e) e
    toks) e -> r
    g [(Key, Value)] -> k -> r
    f = Tokens (TkRecord k e) e
    -> (e -> r) -> (Value -> TkRecord k e -> r) -> r
    forall k e r. Tokens k e -> (e -> r) -> (Value -> k -> r) -> r
    convert Tokens (TkRecord k e) e
    toks e -> r
    g ((Value -> TkRecord k e -> r) -> r)
    -> (Value -> TkRecord k e -> r) -> r
    forall a b. (a -> b) -> a -> b
    $ \ !Value
    v TkRecord k e
    k -> [(Key, Value)]
    -> TkRecord k e -> (e -> r) -> ([(Key, Value)] -> k -> r) -> r
    forall k e r.
    [(Key, Value)]
    -> TkRecord k e -> (e -> r) -> ([(Key, Value)] -> k -> r) -> r
    goR ((Key
    t , Value
    v) (Key, Value) -> [(Key, Value)] -> [(Key, Value)]
    forall a. a -> [a] -> [a]
    : [(Key, Value)]
    acc) TkRecord k e
    k e -> r
    g [(Key, Value)] -> k -> r
    f
        goR ![(Key, Value)]
    acc (TkRecordEnd k
    k) e -> r
    _ [(Key, Value)] -> k -> r
    f = [(Key, Value)] -> k -> r
    f [(Key, Value)]
    acc k
    k
        goR ![(Key, Value)]
    _   (TkRecordErr e
    e) e -> r
    g [(Key, Value)] -> k -> r
    _ = e -> r
    g e
    e

    newtype Result e k a = Result
        { forall e k a.
    Result e k a -> forall r. (e -> r) -> (a -> k -> r) -> r
    unResult :: forall r. (e -> r) -> (a -> k -> r) -> r }