{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE ScopedTypeVariables   #-}

module HaskellWorks.Data.Json.PartialValue
  ( JsonPartialValue(..)
  , JsonPartialValueAt(..)
  , asInteger
  , asString
  , asText
  , castAsInteger
  , entry
  , hasKey
  , hasKV
  , item
  , jsonKeys
  , jsonSize
  , named
  ) where

import Control.Arrow
import Data.String
import Data.Text                                      (Text)
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Json.Internal.Doc
import HaskellWorks.Data.Json.Internal.Orphans        ()
import HaskellWorks.Data.Json.Internal.PartialIndex
import HaskellWorks.Data.Json.Internal.Value
import HaskellWorks.Data.Json.Standard.Cursor.Generic
import HaskellWorks.Data.MQuery
import HaskellWorks.Data.MQuery.AtLeastSize
import HaskellWorks.Data.MQuery.Entry
import HaskellWorks.Data.MQuery.Micro
import HaskellWorks.Data.MQuery.Mini
import HaskellWorks.Data.MQuery.Row
import HaskellWorks.Data.RankSelect.Base.Rank0
import HaskellWorks.Data.RankSelect.Base.Rank1
import HaskellWorks.Data.RankSelect.Base.Select1
import Prelude                                        hiding (drop)
import Text.PrettyPrint.ANSI.Leijen                   hiding ((<$>))

import qualified Data.Attoparsec.ByteString.Char8 as ABC
import qualified Data.ByteString                  as BS
import qualified Data.DList                       as DL
import qualified Data.Text                        as T
import qualified HaskellWorks.Data.BalancedParens as BP

-- | Partial JSON type.
--
-- This data type has an additional 'JsonPartialError' data constructor to indicate parsing
-- errors.  This allows parsing to be more lazy because parsing errors may now be expressed
-- anywhere in the parsed document so the parser no longer needs to make a verdict about whether
-- there are any parsing errors in the entire document.
--
-- See 'jsonPartialJsonValueAt' on how to parse JSON text into this datatype.
--
-- Although this data type allows for lazier parsing it doesn't allow for sub-trees to be
-- garbage collected if a reference to an ancestor node is held.  To avoid holding onto
-- sub-trees that are no longer needed without having to drop references to ancestors use
-- 'HaskellWorks.Data.Json.LightJson.LightJson' instead.
data JsonPartialValue
  = JsonPartialString Text
  | JsonPartialNumber Double
  | JsonPartialObject [(Text, JsonPartialValue)]
  | JsonPartialArray [JsonPartialValue]
  | JsonPartialBool Bool
  | JsonPartialNull
  | JsonPartialError Text
  deriving (JsonPartialValue -> JsonPartialValue -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JsonPartialValue -> JsonPartialValue -> Bool
$c/= :: JsonPartialValue -> JsonPartialValue -> Bool
== :: JsonPartialValue -> JsonPartialValue -> Bool
$c== :: JsonPartialValue -> JsonPartialValue -> Bool
Eq, Int -> JsonPartialValue -> ShowS
[JsonPartialValue] -> ShowS
JsonPartialValue -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JsonPartialValue] -> ShowS
$cshowList :: [JsonPartialValue] -> ShowS
show :: JsonPartialValue -> String
$cshow :: JsonPartialValue -> String
showsPrec :: Int -> JsonPartialValue -> ShowS
$cshowsPrec :: Int -> JsonPartialValue -> ShowS
Show, Eq JsonPartialValue
JsonPartialValue -> JsonPartialValue -> Bool
JsonPartialValue -> JsonPartialValue -> Ordering
JsonPartialValue -> JsonPartialValue -> JsonPartialValue
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JsonPartialValue -> JsonPartialValue -> JsonPartialValue
$cmin :: JsonPartialValue -> JsonPartialValue -> JsonPartialValue
max :: JsonPartialValue -> JsonPartialValue -> JsonPartialValue
$cmax :: JsonPartialValue -> JsonPartialValue -> JsonPartialValue
>= :: JsonPartialValue -> JsonPartialValue -> Bool
$c>= :: JsonPartialValue -> JsonPartialValue -> Bool
> :: JsonPartialValue -> JsonPartialValue -> Bool
$c> :: JsonPartialValue -> JsonPartialValue -> Bool
<= :: JsonPartialValue -> JsonPartialValue -> Bool
$c<= :: JsonPartialValue -> JsonPartialValue -> Bool
< :: JsonPartialValue -> JsonPartialValue -> Bool
$c< :: JsonPartialValue -> JsonPartialValue -> Bool
compare :: JsonPartialValue -> JsonPartialValue -> Ordering
$ccompare :: JsonPartialValue -> JsonPartialValue -> Ordering
Ord)

class JsonPartialValueAt a where
  -- | Get a JSON partial value from another type
  --
  -- This function can always "succeed" because the data type it returns allows for the document value
  -- to contain an arbitrary number of errors.  This means errors can be reported in document nodes
  -- as parsing occurs lazily.
  --
  -- There are garbage collection implementations you may want to consider.  If you would like to be
  -- able to hold onto ancestor nodes and still be able to garbage collect visited sub-trees, then
  -- consider using 'HaskellWorks.Data.Json.LightJson.lightJsonAt' instead.
  jsonPartialJsonValueAt :: a -> JsonPartialValue

data JsonPartialField = JsonPartialField Text JsonPartialValue

jsonPartialValueString :: JsonPartialValue -> Text
jsonPartialValueString :: JsonPartialValue -> Text
jsonPartialValueString JsonPartialValue
pjv = case JsonPartialValue
pjv of
  JsonPartialString Text
s -> Text
s
  JsonPartialValue
_                   -> Text
""

instance JsonPartialValueAt JsonPartialIndex where
  jsonPartialJsonValueAt :: JsonPartialIndex -> JsonPartialValue
jsonPartialJsonValueAt JsonPartialIndex
i = case JsonPartialIndex
i of
    JsonPartialIndexString ByteString
s  -> case forall a. Parser a -> ByteString -> Result a
ABC.parse forall t u. (Parser t u, IsString t) => Parser t String
parseJsonString ByteString
s of
      ABC.Fail    {}  -> Text -> JsonPartialValue
JsonPartialError (Text
"Invalid string: '" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show (Int -> ByteString -> ByteString
BS.take Int
20 ByteString
s)) forall a. Semigroup a => a -> a -> a
<> Text
"...'")
      ABC.Partial ByteString -> IResult ByteString String
_   -> Text -> JsonPartialValue
JsonPartialError Text
"Unexpected end of string"
      ABC.Done    ByteString
_ String
r -> Text -> JsonPartialValue
JsonPartialString (String -> Text
T.pack String
r) -- TODO optimise
    JsonPartialIndexNumber ByteString
s  -> case forall a. Parser a -> ByteString -> Result a
ABC.parse forall a. Fractional a => Parser a
ABC.rational ByteString
s of
      ABC.Fail    {}    -> Text -> JsonPartialValue
JsonPartialError (Text
"Invalid number: '" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show (Int -> ByteString -> ByteString
BS.take Int
20 ByteString
s)) forall a. Semigroup a => a -> a -> a
<> Text
"...'")
      ABC.Partial ByteString -> IResult ByteString Double
f     -> case ByteString -> IResult ByteString Double
f ByteString
" " of
        ABC.Fail    {}  -> Text -> JsonPartialValue
JsonPartialError (Text
"Invalid number: '" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show (Int -> ByteString -> ByteString
BS.take Int
20 ByteString
s)) forall a. Semigroup a => a -> a -> a
<> Text
"...'")
        ABC.Partial ByteString -> IResult ByteString Double
_   -> Text -> JsonPartialValue
JsonPartialError Text
"Unexpected end of number"
        ABC.Done    ByteString
_ Double
r -> Double -> JsonPartialValue
JsonPartialNumber Double
r
      ABC.Done    ByteString
_ Double
r   -> Double -> JsonPartialValue
JsonPartialNumber Double
r
    JsonPartialIndexObject  [(ByteString, JsonPartialIndex)]
fs -> [(Text, JsonPartialValue)] -> JsonPartialValue
JsonPartialObject (forall a b. (a -> b) -> [a] -> [b]
map ((JsonPartialValue -> Text
jsonPartialValueString forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> JsonPartialValue
parseString) forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall a. JsonPartialValueAt a => a -> JsonPartialValue
jsonPartialJsonValueAt) [(ByteString, JsonPartialIndex)]
fs)
    JsonPartialIndexArray   [JsonPartialIndex]
es -> [JsonPartialValue] -> JsonPartialValue
JsonPartialArray (forall a b. (a -> b) -> [a] -> [b]
map forall a. JsonPartialValueAt a => a -> JsonPartialValue
jsonPartialJsonValueAt [JsonPartialIndex]
es)
    JsonPartialIndexBool    Bool
v  -> Bool -> JsonPartialValue
JsonPartialBool Bool
v
    JsonPartialIndex
JsonPartialIndexNull       -> JsonPartialValue
JsonPartialNull
    JsonPartialIndexError String
s    -> Text -> JsonPartialValue
JsonPartialError (String -> Text
T.pack String
s) -- TODO optimise
    where parseString :: ByteString -> JsonPartialValue
parseString ByteString
bs = case forall a. Parser a -> ByteString -> Result a
ABC.parse forall t u. (Parser t u, IsString t) => Parser t String
parseJsonString ByteString
bs of
            ABC.Fail    {}  -> Text -> JsonPartialValue
JsonPartialError (Text
"Invalid field: '" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show (Int -> ByteString -> ByteString
BS.take Int
20 ByteString
bs)) forall a. Semigroup a => a -> a -> a
<> Text
"...'")
            ABC.Partial ByteString -> IResult ByteString String
_   -> Text -> JsonPartialValue
JsonPartialError Text
"Unexpected end of field"
            ABC.Done    ByteString
_ String
s -> Text -> JsonPartialValue
JsonPartialString (String -> Text
T.pack String
s) -- TODO optimise

toJsonPartialField :: (Text, JsonPartialValue) -> JsonPartialField
toJsonPartialField :: (Text, JsonPartialValue) -> JsonPartialField
toJsonPartialField (Text
k, JsonPartialValue
v) = Text -> JsonPartialValue -> JsonPartialField
JsonPartialField Text
k JsonPartialValue
v

instance Pretty JsonPartialField where
  pretty :: JsonPartialField -> Doc
pretty (JsonPartialField Text
k JsonPartialValue
v) = String -> Doc
text (forall a. Show a => a -> String
show Text
k) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
": " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc
pretty JsonPartialValue
v

instance Pretty JsonPartialValue where
  pretty :: JsonPartialValue -> Doc
pretty JsonPartialValue
mjpv = case JsonPartialValue
mjpv of
    JsonPartialString Text
s   -> Doc -> Doc
dullgreen  (String -> Doc
text (forall a. Show a => a -> String
show Text
s))
    JsonPartialNumber Double
n   -> Doc -> Doc
cyan       (String -> Doc
text (forall a. Show a => a -> String
show Double
n))
    JsonPartialObject []  -> String -> Doc
text String
"{}"
    JsonPartialObject [(Text, JsonPartialValue)]
kvs -> Doc -> Doc -> Doc -> [Doc] -> Doc
hEncloseSep (String -> Doc
text String
"{") (String -> Doc
text String
"}") (String -> Doc
text String
",") ((forall a. Pretty a => a -> Doc
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, JsonPartialValue) -> JsonPartialField
toJsonPartialField) forall a b. (a -> b) -> [a] -> [b]
`map` [(Text, JsonPartialValue)]
kvs)
    JsonPartialArray [JsonPartialValue]
vs   -> Doc -> Doc -> Doc -> [Doc] -> Doc
hEncloseSep (String -> Doc
text String
"[") (String -> Doc
text String
"]") (String -> Doc
text String
",") (forall a. Pretty a => a -> Doc
pretty forall a b. (a -> b) -> [a] -> [b]
`map` [JsonPartialValue]
vs)
    JsonPartialBool Bool
w     -> Doc -> Doc
red (String -> Doc
text (forall a. Show a => a -> String
show Bool
w))
    JsonPartialValue
JsonPartialNull       -> String -> Doc
text String
"null"
    JsonPartialError Text
s    -> String -> Doc
text String
"<error " forall a. Semigroup a => a -> a -> a
<> String -> Doc
text (Text -> String
T.unpack Text
s) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
">"

instance Pretty (Micro JsonPartialValue) where
  pretty :: Micro JsonPartialValue -> Doc
pretty (Micro (JsonPartialString Text
s )) = Doc -> Doc
dullgreen (String -> Doc
text (forall a. Show a => a -> String
show Text
s))
  pretty (Micro (JsonPartialNumber Double
n )) = Doc -> Doc
cyan      (String -> Doc
text (forall a. Show a => a -> String
show Double
n))
  pretty (Micro (JsonPartialObject [])) = String -> Doc
text String
"{}"
  pretty (Micro (JsonPartialObject [(Text, JsonPartialValue)]
_ )) = String -> Doc
text String
"{..}"
  pretty (Micro (JsonPartialArray [] )) = String -> Doc
text String
"[]"
  pretty (Micro (JsonPartialArray [JsonPartialValue]
_  )) = String -> Doc
text String
"[..]"
  pretty (Micro (JsonPartialBool Bool
w   )) = Doc -> Doc
red (String -> Doc
text (forall a. Show a => a -> String
show Bool
w))
  pretty (Micro  JsonPartialValue
JsonPartialNull      ) = String -> Doc
text String
"null"
  pretty (Micro (JsonPartialError Text
s  )) = String -> Doc
text String
"<error " forall a. Semigroup a => a -> a -> a
<> String -> Doc
text (Text -> String
T.unpack Text
s) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
">"

instance Pretty (Micro (String, JsonPartialValue)) where
  pretty :: Micro (String, JsonPartialValue) -> Doc
pretty (Micro (String
fieldName, JsonPartialValue
jpv)) = Doc -> Doc
red (String -> Doc
text (forall a. Show a => a -> String
show String
fieldName)) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
": " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc
pretty (forall a. a -> Micro a
Micro JsonPartialValue
jpv)

instance Pretty (Micro (Text, JsonPartialValue)) where
  pretty :: Micro (Text, JsonPartialValue) -> Doc
pretty (Micro (Text
fieldName, JsonPartialValue
jpv)) = Doc -> Doc
red (String -> Doc
text (forall a. Show a => a -> String
show Text
fieldName)) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
": " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc
pretty (forall a. a -> Micro a
Micro JsonPartialValue
jpv)

instance Pretty (Mini JsonPartialValue) where
  pretty :: Mini JsonPartialValue -> Doc
pretty Mini JsonPartialValue
mjpv = case Mini JsonPartialValue
mjpv of
    Mini (JsonPartialString Text
s   ) -> Doc -> Doc
dullgreen  (String -> Doc
text (forall a. Show a => a -> String
show Text
s))
    Mini (JsonPartialNumber Double
n   ) -> Doc -> Doc
cyan       (String -> Doc
text (forall a. Show a => a -> String
show Double
n))
    Mini (JsonPartialObject []  ) -> String -> Doc
text String
"{}"
    Mini (JsonPartialObject [(Text, JsonPartialValue)]
kvs ) -> case [(Text, JsonPartialValue)]
kvs of
      ((Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:(Text, JsonPartialValue)
_:[(Text, JsonPartialValue)]
_) -> String -> Doc
text String
"{" forall a. Semigroup a => a -> a -> a
<> forall a. Pretty (Micro a) => [a] -> Doc
prettyKvs [(Text, JsonPartialValue)]
kvs forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
", ..}"
      []                          -> String -> Doc
text String
"{}"
      [(Text, JsonPartialValue)]
_                           -> String -> Doc
text String
"{" forall a. Semigroup a => a -> a -> a
<> forall a. Pretty (Micro a) => [a] -> Doc
prettyKvs [(Text, JsonPartialValue)]
kvs forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
"}"
    Mini (JsonPartialArray []   ) -> String -> Doc
text String
"[]"
    Mini (JsonPartialArray [JsonPartialValue]
vs   ) | [JsonPartialValue]
vs forall a. AtLeastSize a => a -> Int -> Bool
`atLeastSize` Int
11 -> String -> Doc
text String
"[" forall a. Semigroup a => a -> a -> a
<> Int -> Doc -> Doc
nest Int
2 (forall a. Pretty a => [a] -> Doc
prettyVs (forall a. a -> Micro a
Micro forall a b. (a -> b) -> [a] -> [b]
`map` forall a. Int -> [a] -> [a]
take Int
10 [JsonPartialValue]
vs)) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
", ..]"
    Mini (JsonPartialArray [JsonPartialValue]
vs   ) | [JsonPartialValue]
vs forall a. AtLeastSize a => a -> Int -> Bool
`atLeastSize` Int
1  -> String -> Doc
text String
"[" forall a. Semigroup a => a -> a -> a
<> Int -> Doc -> Doc
nest Int
2 (forall a. Pretty a => [a] -> Doc
prettyVs (forall a. a -> Micro a
Micro forall a b. (a -> b) -> [a] -> [b]
`map` forall a. Int -> [a] -> [a]
take Int
10 [JsonPartialValue]
vs)) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
"]"
    Mini (JsonPartialArray [JsonPartialValue]
_    )                       -> String -> Doc
text String
"[]"
    Mini (JsonPartialBool Bool
w     ) -> Doc -> Doc
red (String -> Doc
text (forall a. Show a => a -> String
show Bool
w))
    Mini  JsonPartialValue
JsonPartialNull         -> String -> Doc
text String
"null"
    Mini (JsonPartialError Text
s    ) -> String -> Doc
text String
"<error " forall a. Semigroup a => a -> a -> a
<> String -> Doc
text (Text -> String
T.unpack Text
s) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
">"

instance Pretty (Mini (Text, JsonPartialValue)) where
  pretty :: Mini (Text, JsonPartialValue) -> Doc
pretty (Mini (Text
fieldName, JsonPartialValue
jpv)) = String -> Doc
text (forall a. Show a => a -> String
show Text
fieldName) forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
": " forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Doc
pretty (forall a. a -> Mini a
Mini JsonPartialValue
jpv)

instance Pretty (MQuery JsonPartialValue) where
  pretty :: MQuery JsonPartialValue -> Doc
pretty = forall a. Pretty a => a -> Doc
pretty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> a -> Row a
Row Int
120 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. MQuery a -> DList a
mQuery

instance Pretty (MQuery (Entry Text JsonPartialValue)) where
  pretty :: MQuery (Entry Text JsonPartialValue) -> Doc
pretty (MQuery DList (Entry Text JsonPartialValue)
das) = forall a. Pretty a => a -> Doc
pretty (forall a. Int -> a -> Row a
Row Int
120 DList (Entry Text JsonPartialValue)
das)

instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => JsonPartialValueAt (GenericCursor BS.ByteString v w) where
  jsonPartialJsonValueAt :: GenericCursor ByteString v w -> JsonPartialValue
jsonPartialJsonValueAt = forall a. JsonPartialValueAt a => a -> JsonPartialValue
jsonPartialJsonValueAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. JsonPartialIndexAt a => a -> JsonPartialIndex
jsonPartialIndexAt

hasKV :: Text -> JsonPartialValue -> JsonPartialValue -> MQuery JsonPartialValue
hasKV :: Text
-> JsonPartialValue -> JsonPartialValue -> MQuery JsonPartialValue
hasKV Text
k JsonPartialValue
v (JsonPartialObject [(Text, JsonPartialValue)]
xs) = if (Text
k, JsonPartialValue
v) forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [(Text, JsonPartialValue)]
xs then forall a. DList a -> MQuery a
MQuery (forall a. a -> DList a
DL.singleton ([(Text, JsonPartialValue)] -> JsonPartialValue
JsonPartialObject [(Text, JsonPartialValue)]
xs)) else forall a. DList a -> MQuery a
MQuery forall a. DList a
DL.empty
hasKV Text
_ JsonPartialValue
_  JsonPartialValue
_                     = forall a. DList a -> MQuery a
MQuery forall a. DList a
DL.empty

item :: JsonPartialValue -> MQuery JsonPartialValue
item :: JsonPartialValue -> MQuery JsonPartialValue
item JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialArray [JsonPartialValue]
es -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. [a] -> DList a
DL.fromList [JsonPartialValue]
es
  JsonPartialValue
_                   -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

entry :: JsonPartialValue -> MQuery (Entry Text JsonPartialValue)
entry :: JsonPartialValue -> MQuery (Entry Text JsonPartialValue)
entry JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialObject [(Text, JsonPartialValue)]
fs -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. [a] -> DList a
DL.fromList (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall k v. k -> v -> Entry k v
Entry forall a b. (a -> b) -> [a] -> [b]
`map` [(Text, JsonPartialValue)]
fs)
  JsonPartialValue
_                    -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

asString :: JsonPartialValue -> MQuery String
asString :: JsonPartialValue -> MQuery String
asString JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialString Text
s -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton (Text -> String
T.unpack Text
s)
  JsonPartialValue
_                   -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

asText :: JsonPartialValue -> MQuery Text
asText :: JsonPartialValue -> MQuery Text
asText JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialString Text
s -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton Text
s
  JsonPartialValue
_                   -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

asInteger :: JsonPartialValue -> MQuery Integer
asInteger :: JsonPartialValue -> MQuery Integer
asInteger JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialNumber Double
n -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton (forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n)
  JsonPartialValue
_                   -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

castAsInteger :: JsonPartialValue -> MQuery Integer
castAsInteger :: JsonPartialValue -> MQuery Integer
castAsInteger JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialString Text
n -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton (forall a. Read a => String -> a
read (Text -> String
T.unpack Text
n))
  JsonPartialNumber Double
n -> forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton (forall a b. (RealFrac a, Integral b) => a -> b
floor Double
n)
  JsonPartialValue
_                   -> forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

named :: Text -> Entry Text JsonPartialValue -> MQuery JsonPartialValue
named :: Text -> Entry Text JsonPartialValue -> MQuery JsonPartialValue
named Text
fieldName (Entry Text
fieldName' JsonPartialValue
jpv) | Text
fieldName forall a. Eq a => a -> a -> Bool
== Text
fieldName'  = forall a. DList a -> MQuery a
MQuery forall a b. (a -> b) -> a -> b
$ forall a. a -> DList a
DL.singleton JsonPartialValue
jpv
named Text
_         Entry Text JsonPartialValue
_                      = forall a. DList a -> MQuery a
MQuery   forall a. DList a
DL.empty

jsonKeys :: JsonPartialValue -> [Text]
jsonKeys :: JsonPartialValue -> [Text]
jsonKeys JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialObject [(Text, JsonPartialValue)]
fs -> forall a b. (a, b) -> a
fst forall a b. (a -> b) -> [a] -> [b]
`map` [(Text, JsonPartialValue)]
fs
  JsonPartialValue
_                    -> []

hasKey :: Text -> JsonPartialValue -> Bool
hasKey :: Text -> JsonPartialValue -> Bool
hasKey Text
fieldName JsonPartialValue
jpv = Text
fieldName forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` JsonPartialValue -> [Text]
jsonKeys JsonPartialValue
jpv

jsonSize :: JsonPartialValue -> MQuery JsonPartialValue
jsonSize :: JsonPartialValue -> MQuery JsonPartialValue
jsonSize JsonPartialValue
jpv = case JsonPartialValue
jpv of
  JsonPartialArray  [JsonPartialValue]
es -> forall a. DList a -> MQuery a
MQuery (forall a. a -> DList a
DL.singleton (Double -> JsonPartialValue
JsonPartialNumber (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [JsonPartialValue]
es))))
  JsonPartialObject [(Text, JsonPartialValue)]
es -> forall a. DList a -> MQuery a
MQuery (forall a. a -> DList a
DL.singleton (Double -> JsonPartialValue
JsonPartialNumber (forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, JsonPartialValue)]
es))))
  JsonPartialValue
_                    -> forall a. DList a -> MQuery a
MQuery (forall a. a -> DList a
DL.singleton (Double -> JsonPartialValue
JsonPartialNumber Double
0))