{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveTraversable          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE TypeFamilies               #-}
-- |
-- Module: Data.Greskell.GMap
-- Description: data type for g:Map
-- Maintainer: Toshio Ito <debug.ito@gmail.com>
--
-- @since 0.1.2.0
--
-- This module defines types for parsing a "g:Map" GraphSON
-- object. Usually users only have to use 'GMapEntry', because other
-- types are just used internally to implement GraphSON parsers.
module Data.Greskell.GMap
    ( -- * FlattenedMap
      FlattenedMap (..)
    , parseToFlattenedMap
      -- * GMap
    , GMap (..)
    , unGMap
    , singleton
    , toList
    , parseToGMap
      -- * GMapEntry
    , GMapEntry (..)
    , unGMapEntry
    , parseToGMapEntry
      -- * Examples
    , examples
    ) where

import           Control.Applicative                  (empty, (<$>), (<*>), (<|>))
import           Data.Aeson                           (FromJSON (..), FromJSONKey,
                                                       FromJSONKeyFunction (..), ToJSON (..),
                                                       ToJSONKey, Value (..), fromJSONKey)
import qualified Data.Aeson                           as Aeson
import qualified Data.Aeson.Key                       as Key
import           Data.Aeson.KeyMap                    (KeyMap)
import qualified Data.Aeson.KeyMap                    as KM
import           Data.Aeson.Types                     (Parser)
import qualified Data.ByteString.Lazy.Char8           as BSLC
import           Data.Either                          (isLeft)
import           Data.Foldable                        (Foldable, length)
import           Data.Hashable                        (Hashable)
import           Data.HashMap.Strict                  (HashMap)
import qualified Data.HashMap.Strict                  as HashMap
import           Data.List                            (sort)
import qualified Data.Map                             as M
import           Data.Text                            (Text, intercalate, unpack)
import           Data.Traversable                     (Traversable, traverse)
import           Data.Vector                          (Vector, (!))
import qualified Data.Vector                          as V
import           GHC.Exts                             (IsList (Item))
import qualified GHC.Exts                             as List (IsList (fromList, toList))


#if MIN_VERSION_aeson(1,5,0)
import           Data.Coerce                          (coerce)
#else
import           Unsafe.Coerce                        (unsafeCoerce)
#endif

import           Data.Greskell.GraphSON.GraphSONTyped (GraphSONTyped (..))

-- | JSON encoding of a map as an array of flattened key-value pairs.
--
-- 'ToJSON' instance of this type encodes the internal map as an array
-- of keys and values. 'FromJSON' instance of this type parses that
-- flattened map.
--
-- - type @c@: container type for a map (e.g. 'Data.Map.Map' and
--   'Data.HashMap.Strict.HashMap').
-- - type @k@: key of the map.
-- - type @v@: value of the map.
newtype FlattenedMap c k v
  = FlattenedMap { forall (c :: * -> * -> *) k v. FlattenedMap c k v -> c k v
unFlattenedMap :: c k v }
  deriving (FlattenedMap c k v -> FlattenedMap c k v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (c :: * -> * -> *) k v.
Eq (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
/= :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c/= :: forall (c :: * -> * -> *) k v.
Eq (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
== :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c== :: forall (c :: * -> * -> *) k v.
Eq (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
Eq, forall a. Eq a => a -> FlattenedMap c k a -> Bool
forall a. Num a => FlattenedMap c k a -> a
forall a. Ord a => FlattenedMap c k a -> a
forall m. Monoid m => FlattenedMap c k m -> m
forall a. FlattenedMap c k a -> Bool
forall a. FlattenedMap c k a -> Int
forall a. FlattenedMap c k a -> [a]
forall a. (a -> a -> a) -> FlattenedMap c k a -> a
forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m
forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b
forall a b. (a -> b -> b) -> b -> FlattenedMap c k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> FlattenedMap c k a -> Bool
forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
FlattenedMap c k m -> m
forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Bool
forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Int
forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> [a]
forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> FlattenedMap c k a -> a
forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> FlattenedMap c k a -> m
forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> FlattenedMap c k a -> b
forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> FlattenedMap c k a -> b
product :: forall a. Num a => FlattenedMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
sum :: forall a. Num a => FlattenedMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
minimum :: forall a. Ord a => FlattenedMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
maximum :: forall a. Ord a => FlattenedMap c k a -> a
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
elem :: forall a. Eq a => a -> FlattenedMap c k a -> Bool
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> FlattenedMap c k a -> Bool
length :: forall a. FlattenedMap c k a -> Int
$clength :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Int
null :: forall a. FlattenedMap c k a -> Bool
$cnull :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Bool
toList :: forall a. FlattenedMap c k a -> [a]
$ctoList :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> [a]
foldl1 :: forall a. (a -> a -> a) -> FlattenedMap c k a -> a
$cfoldl1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> FlattenedMap c k a -> a
foldr1 :: forall a. (a -> a -> a) -> FlattenedMap c k a -> a
$cfoldr1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> FlattenedMap c k a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b
$cfoldl' :: forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> FlattenedMap c k a -> b
foldl :: forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b
$cfoldl :: forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> FlattenedMap c k a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> FlattenedMap c k a -> b
$cfoldr' :: forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> FlattenedMap c k a -> b
foldr :: forall a b. (a -> b -> b) -> b -> FlattenedMap c k a -> b
$cfoldr :: forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> FlattenedMap c k a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m
$cfoldMap' :: forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> FlattenedMap c k a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m
$cfoldMap :: forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> FlattenedMap c k a -> m
fold :: forall m. Monoid m => FlattenedMap c k m -> m
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
FlattenedMap c k m -> m
Foldable, forall a b. a -> FlattenedMap c k b -> FlattenedMap c k a
forall a b. (a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> FlattenedMap c k b -> FlattenedMap c k a
forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
<$ :: forall a b. a -> FlattenedMap c k b -> FlattenedMap c k a
$c<$ :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> FlattenedMap c k b -> FlattenedMap c k a
fmap :: forall a b. (a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
$cfmap :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
Functor, FlattenedMap c k v -> FlattenedMap c k v -> Bool
FlattenedMap c k v -> FlattenedMap c k v -> Ordering
FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
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
forall {c :: * -> * -> *} {k} {v}.
Ord (c k v) =>
Eq (FlattenedMap c k v)
forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Ordering
forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
min :: FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
$cmin :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
max :: FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
$cmax :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v
>= :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c>= :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
> :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c> :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
<= :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c<= :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
< :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$c< :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Bool
compare :: FlattenedMap c k v -> FlattenedMap c k v -> Ordering
$ccompare :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Ordering
Ord, Int -> FlattenedMap c k v -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> FlattenedMap c k v -> ShowS
forall (c :: * -> * -> *) k v.
Show (c k v) =>
[FlattenedMap c k v] -> ShowS
forall (c :: * -> * -> *) k v.
Show (c k v) =>
FlattenedMap c k v -> String
showList :: [FlattenedMap c k v] -> ShowS
$cshowList :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
[FlattenedMap c k v] -> ShowS
show :: FlattenedMap c k v -> String
$cshow :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
FlattenedMap c k v -> String
showsPrec :: Int -> FlattenedMap c k v -> ShowS
$cshowsPrec :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> FlattenedMap c k v -> ShowS
Show, forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
forall {c :: * -> * -> *} {k}.
Traversable (c k) =>
Functor (FlattenedMap c k)
forall {c :: * -> * -> *} {k}.
Traversable (c k) =>
Foldable (FlattenedMap c k)
forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
sequence :: forall (m :: * -> *) a.
Monad m =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
$csequence :: forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
$cmapM :: forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
$csequenceA :: forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
$ctraverse :: forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
Traversable)

-- | Use 'parseToFlattenedMap'.
instance (FromJSON k, FromJSON v, IsList (c k v), Item (c k v) ~ (k,v)) => FromJSON (FlattenedMap c k v) where
  parseJSON :: Value -> Parser (FlattenedMap c k v)
parseJSON (Array Array
v) = forall (c :: * -> * -> *) k v s.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (FlattenedMap c k v)
parseToFlattenedMap forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser a
parseJSON Array
v
  parseJSON Value
v         = forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Array, but got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Value
v)

-- | Parse a flattened key-values to an associative Vector.
parseToAVec :: (s -> Parser k) -> (s -> Parser v) -> Vector s -> Parser (Vector (k,v))
parseToAVec :: forall s k v.
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (Vector (k, v))
parseToAVec s -> Parser k
parseKey s -> Parser v
parseValue Vector s
v =
  if forall a. Integral a => a -> Bool
odd Int
vlen
  then forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Fail to parse a list into an associative list because there are odd number of elements."
  else forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (s, s) -> Parser (k, v)
parsePair Vector (s, s)
pairVec
  where
    vlen :: Int
vlen = forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector s
v
    pairVec :: Vector (s, s)
pairVec = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Int
i -> (Vector s
v forall a. Vector a -> Int -> a
! (Int
i forall a. Num a => a -> a -> a
* Int
2), Vector s
v forall a. Vector a -> Int -> a
! (Int
i forall a. Num a => a -> a -> a
* Int
2 forall a. Num a => a -> a -> a
+ Int
1))) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Vector a
V.fromList [Int
0 .. ((Int
vlen forall a. Integral a => a -> a -> a
`div` Int
2) forall a. Num a => a -> a -> a
- Int
1)]
    parsePair :: (s, s) -> Parser (k, v)
parsePair (s
vk, s
vv) = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> Parser k
parseKey s
vk forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> s -> Parser v
parseValue s
vv

-- | General parser for 'FlattenedMap'.
parseToFlattenedMap :: (IsList (c k v), Item (c k v) ~ (k,v))
                    => (s -> Parser k) -- ^ key parser
                    -> (s -> Parser v) -- ^ value parser
                    -> Vector s -- ^ input vector of flattened key-values.
                    -> Parser (FlattenedMap c k v)
parseToFlattenedMap :: forall (c :: * -> * -> *) k v s.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (FlattenedMap c k v)
parseToFlattenedMap s -> Parser k
parseKey s -> Parser v
parseValue Vector s
v =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l. IsList l => [Item l] -> l
List.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
V.toList) forall a b. (a -> b) -> a -> b
$ forall s k v.
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (Vector (k, v))
parseToAVec s -> Parser k
parseKey s -> Parser v
parseValue Vector s
v

instance (ToJSON k, ToJSON v, IsList (c k v), Item (c k v) ~ (k,v)) => ToJSON (FlattenedMap c k v) where
  toJSON :: FlattenedMap c k v -> Value
toJSON (FlattenedMap c k v
m) = forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ forall {b}. [(b, b)] -> [b]
flatten forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (ToJSON a, ToJSON a) => (a, a) -> (Value, Value)
toValuePair forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
List.toList c k v
m
    where
      toValuePair :: (a, a) -> (Value, Value)
toValuePair (a
k, a
v) = (forall a. ToJSON a => a -> Value
toJSON a
k, forall a. ToJSON a => a -> Value
toJSON a
v)
      flatten :: [(b, b)] -> [b]
flatten [(b, b)]
pl = (\(b
k, b
v) -> [b
k, b
v]) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [(b, b)]
pl

-- | Map to \"g:Map\".
instance GraphSONTyped (FlattenedMap c k v) where
  gsonTypeFor :: FlattenedMap c k v -> Text
gsonTypeFor FlattenedMap c k v
_ = Text
"g:Map"


-- | Haskell representation of @g:Map@ type.
--
-- GraphSON v1 and v2 encode Java @Map@ type as a JSON Object, while
-- GraphSON v3 encodes it as an array of flattened keys and values
-- (like 'FlattenedMap'.)  'GMap' type handles both encoding schemes.
--
-- - type @c@: container type for a map (e.g. 'Data.Map.Map' and
--   'Data.HashMap.Strict.HashMap').
-- - type @k@: key of the map.
-- - type @v@: value of the map.
data GMap c k v
  = GMap
      { forall (c :: * -> * -> *) k v. GMap c k v -> Bool
gmapFlat  :: !Bool
        -- ^ If 'True', the map is encoded as an array. If 'False', it's
        -- encoded as a JSON Object.
      , forall (c :: * -> * -> *) k v. GMap c k v -> c k v
gmapValue :: !(c k v)
        -- ^ Map implementation.
      }
  deriving (GMap c k v -> GMap c k v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (c :: * -> * -> *) k v.
Eq (c k v) =>
GMap c k v -> GMap c k v -> Bool
/= :: GMap c k v -> GMap c k v -> Bool
$c/= :: forall (c :: * -> * -> *) k v.
Eq (c k v) =>
GMap c k v -> GMap c k v -> Bool
== :: GMap c k v -> GMap c k v -> Bool
$c== :: forall (c :: * -> * -> *) k v.
Eq (c k v) =>
GMap c k v -> GMap c k v -> Bool
Eq, forall a. GMap c k a -> Bool
forall m a. Monoid m => (a -> m) -> GMap c k a -> m
forall a b. (a -> b -> b) -> b -> GMap c k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> GMap c k a -> Bool
forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
GMap c k m -> m
forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Bool
forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Int
forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> [a]
forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> GMap c k a -> a
forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> GMap c k a -> m
forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> GMap c k a -> b
forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> GMap c k a -> b
product :: forall a. Num a => GMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
sum :: forall a. Num a => GMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
minimum :: forall a. Ord a => GMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
maximum :: forall a. Ord a => GMap c k a -> a
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
elem :: forall a. Eq a => a -> GMap c k a -> Bool
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> GMap c k a -> Bool
length :: forall a. GMap c k a -> Int
$clength :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Int
null :: forall a. GMap c k a -> Bool
$cnull :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Bool
toList :: forall a. GMap c k a -> [a]
$ctoList :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> [a]
foldl1 :: forall a. (a -> a -> a) -> GMap c k a -> a
$cfoldl1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> GMap c k a -> a
foldr1 :: forall a. (a -> a -> a) -> GMap c k a -> a
$cfoldr1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> GMap c k a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> GMap c k a -> b
$cfoldl' :: forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> GMap c k a -> b
foldl :: forall b a. (b -> a -> b) -> b -> GMap c k a -> b
$cfoldl :: forall (c :: * -> * -> *) k b a.
Foldable (c k) =>
(b -> a -> b) -> b -> GMap c k a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> GMap c k a -> b
$cfoldr' :: forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> GMap c k a -> b
foldr :: forall a b. (a -> b -> b) -> b -> GMap c k a -> b
$cfoldr :: forall (c :: * -> * -> *) k a b.
Foldable (c k) =>
(a -> b -> b) -> b -> GMap c k a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> GMap c k a -> m
$cfoldMap' :: forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> GMap c k a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> GMap c k a -> m
$cfoldMap :: forall (c :: * -> * -> *) k m a.
(Foldable (c k), Monoid m) =>
(a -> m) -> GMap c k a -> m
fold :: forall m. Monoid m => GMap c k m -> m
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
GMap c k m -> m
Foldable, forall a b. a -> GMap c k b -> GMap c k a
forall a b. (a -> b) -> GMap c k a -> GMap c k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> GMap c k b -> GMap c k a
forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> GMap c k a -> GMap c k b
<$ :: forall a b. a -> GMap c k b -> GMap c k a
$c<$ :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> GMap c k b -> GMap c k a
fmap :: forall a b. (a -> b) -> GMap c k a -> GMap c k b
$cfmap :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> GMap c k a -> GMap c k b
Functor, Int -> GMap c k v -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> GMap c k v -> ShowS
forall (c :: * -> * -> *) k v.
Show (c k v) =>
[GMap c k v] -> ShowS
forall (c :: * -> * -> *) k v. Show (c k v) => GMap c k v -> String
showList :: [GMap c k v] -> ShowS
$cshowList :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
[GMap c k v] -> ShowS
show :: GMap c k v -> String
$cshow :: forall (c :: * -> * -> *) k v. Show (c k v) => GMap c k v -> String
showsPrec :: Int -> GMap c k v -> ShowS
$cshowsPrec :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> GMap c k v -> ShowS
Show, forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
forall {c :: * -> * -> *} {k}.
Traversable (c k) =>
Functor (GMap c k)
forall {c :: * -> * -> *} {k}.
Traversable (c k) =>
Foldable (GMap c k)
forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
GMap c k (m a) -> m (GMap c k a)
forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
GMap c k (f a) -> f (GMap c k a)
forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
sequence :: forall (m :: * -> *) a. Monad m => GMap c k (m a) -> m (GMap c k a)
$csequence :: forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
GMap c k (m a) -> m (GMap c k a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
$cmapM :: forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
GMap c k (f a) -> f (GMap c k a)
$csequenceA :: forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
GMap c k (f a) -> f (GMap c k a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
$ctraverse :: forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
Traversable)

-- | General parser for 'GMap'.
parseToGMap :: (IsList (c k v), Item (c k v) ~ (k,v))
            => (s -> Parser k) -- ^ key parser
            -> (s -> Parser v) -- ^ value parser
            -> (KeyMap s -> Parser (c k v)) -- ^ object parser
            -> Either (KeyMap s) (Vector s) -- ^ input object or flattened key-values.
            -> Parser (GMap c k v)
parseToGMap :: forall (c :: * -> * -> *) k v s.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
(s -> Parser k)
-> (s -> Parser v)
-> (KeyMap s -> Parser (c k v))
-> Either (KeyMap s) (Vector s)
-> Parser (GMap c k v)
parseToGMap s -> Parser k
_ s -> Parser v
_ KeyMap s -> Parser (c k v)
op (Left KeyMap s
o)   = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
False) forall a b. (a -> b) -> a -> b
$ KeyMap s -> Parser (c k v)
op KeyMap s
o
parseToGMap s -> Parser k
kp s -> Parser v
vp KeyMap s -> Parser (c k v)
_ (Right Vector s
v) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
True forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (c :: * -> * -> *) k v. FlattenedMap c k v -> c k v
unFlattenedMap) forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v s.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (FlattenedMap c k v)
parseToFlattenedMap s -> Parser k
kp s -> Parser v
vp Vector s
v

-- | Use 'parseToGMap'.
instance (FromJSON k, FromJSON v, IsList (c k v), Item (c k v) ~ (k,v), FromJSON (c k v)) => FromJSON (GMap c k v) where
  parseJSON :: Value -> Parser (GMap c k v)
parseJSON Value
v = case Value
v of
    Object Object
o -> Either Object Array -> Parser (GMap c k v)
parse forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left Object
o
    Array Array
a  -> Either Object Array -> Parser (GMap c k v)
parse forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Array
a
    Value
other    -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Object or Array, but got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Value
other)
    where
      parse :: Either Object Array -> Parser (GMap c k v)
parse = forall (c :: * -> * -> *) k v s.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
(s -> Parser k)
-> (s -> Parser v)
-> (KeyMap s -> Parser (c k v))
-> Either (KeyMap s) (Vector s)
-> Parser (GMap c k v)
parseToGMap forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser a
parseJSON (forall a. FromJSON a => Value -> Parser a
parseJSON forall b c a. (b -> c) -> (a -> b) -> a -> c
. Object -> Value
Object)

instance (ToJSON k, ToJSON v, IsList (c k v), Item (c k v) ~ (k,v), ToJSON (c k v)) => ToJSON (GMap c k v) where
  toJSON :: GMap c k v -> Value
toJSON GMap c k v
gm = if forall (c :: * -> * -> *) k v. GMap c k v -> Bool
gmapFlat GMap c k v
gm
              then forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. GMap c k v -> c k v
unGMap GMap c k v
gm
              else forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. GMap c k v -> c k v
unGMap GMap c k v
gm

-- | Map to \"g:Map\".
instance GraphSONTyped (GMap c k v) where
  gsonTypeFor :: GMap c k v -> Text
gsonTypeFor GMap c k v
_ = Text
"g:Map"

-- | Get the map implementation from 'GMap'.
unGMap :: GMap c k v -> c k v
unGMap :: forall (c :: * -> * -> *) k v. GMap c k v -> c k v
unGMap = forall (c :: * -> * -> *) k v. GMap c k v -> c k v
gmapValue

-- | Haskell representation of @Map.Entry@ type.
--
-- Basically GraphSON encodes Java's @Map.Entry@ type as if it were a
-- @Map@ with a single entry. Thus its encoded form is either a JSON
-- object or a flattened key-values, as explained in 'GMap'.
--
-- In old versions of TinkerPop, @Map.Entry@ is encoded as a JSON
-- object with \"key\" and \"value\" fields. 'FromJSON' instance of
-- 'GMapEntry' supports this format as well, but 'ToJSON' instance
-- doesn't support it.
data GMapEntry k v
  = GMapEntry
      { forall k v. GMapEntry k v -> Bool
gmapEntryFlat  :: !Bool
      , forall k v. GMapEntry k v -> k
gmapEntryKey   :: !k
      , forall k v. GMapEntry k v -> v
gmapEntryValue :: !v
      }
  deriving (GMapEntry k v -> GMapEntry k v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. (Eq k, Eq v) => GMapEntry k v -> GMapEntry k v -> Bool
/= :: GMapEntry k v -> GMapEntry k v -> Bool
$c/= :: forall k v. (Eq k, Eq v) => GMapEntry k v -> GMapEntry k v -> Bool
== :: GMapEntry k v -> GMapEntry k v -> Bool
$c== :: forall k v. (Eq k, Eq v) => GMapEntry k v -> GMapEntry k v -> Bool
Eq, forall a. GMapEntry k a -> Bool
forall k a. Eq a => a -> GMapEntry k a -> Bool
forall k a. Num a => GMapEntry k a -> a
forall k a. Ord a => GMapEntry k a -> a
forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m
forall k m. Monoid m => GMapEntry k m -> m
forall k v. GMapEntry k v -> Bool
forall k a. GMapEntry k a -> Int
forall k a. GMapEntry k a -> [a]
forall a b. (a -> b -> b) -> b -> GMapEntry k a -> b
forall k a. (a -> a -> a) -> GMapEntry k a -> a
forall k m a. Monoid m => (a -> m) -> GMapEntry k a -> m
forall k b a. (b -> a -> b) -> b -> GMapEntry k a -> b
forall k a b. (a -> b -> b) -> b -> GMapEntry k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => GMapEntry k a -> a
$cproduct :: forall k a. Num a => GMapEntry k a -> a
sum :: forall a. Num a => GMapEntry k a -> a
$csum :: forall k a. Num a => GMapEntry k a -> a
minimum :: forall a. Ord a => GMapEntry k a -> a
$cminimum :: forall k a. Ord a => GMapEntry k a -> a
maximum :: forall a. Ord a => GMapEntry k a -> a
$cmaximum :: forall k a. Ord a => GMapEntry k a -> a
elem :: forall a. Eq a => a -> GMapEntry k a -> Bool
$celem :: forall k a. Eq a => a -> GMapEntry k a -> Bool
length :: forall a. GMapEntry k a -> Int
$clength :: forall k a. GMapEntry k a -> Int
null :: forall a. GMapEntry k a -> Bool
$cnull :: forall k v. GMapEntry k v -> Bool
toList :: forall a. GMapEntry k a -> [a]
$ctoList :: forall k a. GMapEntry k a -> [a]
foldl1 :: forall a. (a -> a -> a) -> GMapEntry k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldr1 :: forall a. (a -> a -> a) -> GMapEntry k a -> a
$cfoldr1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> GMapEntry k a -> b
$cfoldl' :: forall k b a. (b -> a -> b) -> b -> GMapEntry k a -> b
foldl :: forall b a. (b -> a -> b) -> b -> GMapEntry k a -> b
$cfoldl :: forall k b a. (b -> a -> b) -> b -> GMapEntry k a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> GMapEntry k a -> b
$cfoldr' :: forall k a b. (a -> b -> b) -> b -> GMapEntry k a -> b
foldr :: forall a b. (a -> b -> b) -> b -> GMapEntry k a -> b
$cfoldr :: forall k a b. (a -> b -> b) -> b -> GMapEntry k a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m
$cfoldMap' :: forall k m a. Monoid m => (a -> m) -> GMapEntry k a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m
$cfoldMap :: forall k m a. Monoid m => (a -> m) -> GMapEntry k a -> m
fold :: forall m. Monoid m => GMapEntry k m -> m
$cfold :: forall k m. Monoid m => GMapEntry k m -> m
Foldable, forall a b. a -> GMapEntry k b -> GMapEntry k a
forall a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
forall k a b. a -> GMapEntry k b -> GMapEntry k a
forall k a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> GMapEntry k b -> GMapEntry k a
$c<$ :: forall k a b. a -> GMapEntry k b -> GMapEntry k a
fmap :: forall a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
$cfmap :: forall k a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
Functor, GMapEntry k v -> GMapEntry k v -> Bool
GMapEntry k v -> GMapEntry k v -> Ordering
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
forall {k} {v}. (Ord k, Ord v) => Eq (GMapEntry k v)
forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Bool
forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Ordering
forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> GMapEntry k v
min :: GMapEntry k v -> GMapEntry k v -> GMapEntry k v
$cmin :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> GMapEntry k v
max :: GMapEntry k v -> GMapEntry k v -> GMapEntry k v
$cmax :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> GMapEntry k v
>= :: GMapEntry k v -> GMapEntry k v -> Bool
$c>= :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Bool
> :: GMapEntry k v -> GMapEntry k v -> Bool
$c> :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Bool
<= :: GMapEntry k v -> GMapEntry k v -> Bool
$c<= :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Bool
< :: GMapEntry k v -> GMapEntry k v -> Bool
$c< :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Bool
compare :: GMapEntry k v -> GMapEntry k v -> Ordering
$ccompare :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Ordering
Ord, Int -> GMapEntry k v -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> GMapEntry k v -> ShowS
forall k v. (Show k, Show v) => [GMapEntry k v] -> ShowS
forall k v. (Show k, Show v) => GMapEntry k v -> String
showList :: [GMapEntry k v] -> ShowS
$cshowList :: forall k v. (Show k, Show v) => [GMapEntry k v] -> ShowS
show :: GMapEntry k v -> String
$cshow :: forall k v. (Show k, Show v) => GMapEntry k v -> String
showsPrec :: Int -> GMapEntry k v -> ShowS
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> GMapEntry k v -> ShowS
Show, forall k. Functor (GMapEntry k)
forall k. Foldable (GMapEntry k)
forall k (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
forall k (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
sequence :: forall (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
$csequence :: forall k (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
$cmapM :: forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
$csequenceA :: forall k (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
$ctraverse :: forall k (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
Traversable)

parseKeyValueToEntry :: (s -> Parser k)
                     -> (s -> Parser v)
                     -> KeyMap s
                     -> Parser (Maybe (GMapEntry k v))
parseKeyValueToEntry :: forall s k v.
(s -> Parser k)
-> (s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
parseKeyValueToEntry s -> Parser k
kp s -> Parser v
vp KeyMap s
o =
  if forall (t :: * -> *) a. Foldable t => t a -> Int
length KeyMap s
o forall a. Eq a => a -> a -> Bool
/= Int
2
  then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  else do
    Maybe k
mk <- forall a v. (a -> Parser v) -> Maybe a -> Parser (Maybe v)
parseIfPresent s -> Parser k
kp forall a b. (a -> b) -> a -> b
$ forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"key" KeyMap s
o
    Maybe v
mv <- forall a v. (a -> Parser v) -> Maybe a -> Parser (Maybe v)
parseIfPresent s -> Parser v
vp forall a b. (a -> b) -> a -> b
$ forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"value" KeyMap s
o
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
False forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe k
mk forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe v
mv
  where
    parseIfPresent :: (a -> Parser v) -> Maybe a -> Parser (Maybe v)
    parseIfPresent :: forall a v. (a -> Parser v) -> Maybe a -> Parser (Maybe v)
parseIfPresent a -> Parser v
f = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Parser v
f)

parseSingleEntryObjectToEntry :: FromJSONKey k
                              => (s -> Parser v)
                              -> KeyMap s
                              -> Parser (Maybe (GMapEntry k v))
parseSingleEntryObjectToEntry :: forall k s v.
FromJSONKey k =>
(s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
parseSingleEntryObjectToEntry s -> Parser v
vp KeyMap s
o =
  case forall v. KeyMap v -> [(Key, v)]
KM.toList KeyMap s
o of
   [(Key
raw_key, s
raw_val)] -> do
     k
key <- Text -> Parser k
parseKey forall a b. (a -> b) -> a -> b
$ Key -> Text
Key.toText Key
raw_key
     v
val <- s -> Parser v
vp s
raw_val
     forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
False k
key v
val
   [(Key, s)]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  where
    parseKey :: Text -> Parser k
parseKey Text
k = do
      Text -> Parser k
p <- Parser (Text -> Parser k)
getParser
      Text -> Parser k
p Text
k
    getParser :: Parser (Text -> Parser k)
getParser = case forall a. FromJSONKey a => FromJSONKeyFunction a
fromJSONKey of
      FromJSONKeyText Text -> k
p -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) a. Monad m => a -> m a
return Text -> k
p
      FromJSONKeyTextParser Text -> Parser k
p -> forall (m :: * -> *) a. Monad m => a -> m a
return Text -> Parser k
p
      FromJSONKeyValue Value -> Parser k
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail ( String
"Unexpected FromJSONKeyValue."
                                   forall a. [a] -> [a] -> [a]
++ String
" It expects that the entry key is parsed from the text key in JSON Object,"
                                   forall a. [a] -> [a] -> [a]
++ String
" but the key type does not support it."
                                 )
      FromJSONKeyFunction k
FromJSONKeyCoerce -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) a. Monad m => a -> m a
return coerce :: forall a b. Coercible a b => a -> b
coerce

orElseM :: Monad m => m (Maybe a) -> m (Maybe a) -> m (Maybe a)
orElseM :: forall (m :: * -> *) a.
Monad m =>
m (Maybe a) -> m (Maybe a) -> m (Maybe a)
orElseM m (Maybe a)
act_a m (Maybe a)
act_b = do
  Maybe a
ma <- m (Maybe a)
act_a
  case Maybe a
ma of
   Just a
a  -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
a
   Maybe a
Nothing -> m (Maybe a)
act_b

-- | General parser for 'GMapEntry'.
parseToGMapEntry :: FromJSONKey k
                 => (s -> Parser k) -- ^ key parser
                 -> (s -> Parser v) -- ^ value parser
                 -> Either (KeyMap s) (Vector s) -- ^ input object or flattened key-values
                 -> Parser (GMapEntry k v)
parseToGMapEntry :: forall k s v.
FromJSONKey k =>
(s -> Parser k)
-> (s -> Parser v)
-> Either (KeyMap s) (Vector s)
-> Parser (GMapEntry k v)
parseToGMapEntry s -> Parser k
kp s -> Parser v
vp (Right Vector s
vec) = do
  Vector (k, v)
avec <- forall s k v.
(s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (Vector (k, v))
parseToAVec s -> Parser k
kp s -> Parser v
vp Vector s
vec
  case forall a. Vector a -> [a]
V.toList Vector (k, v)
avec of
   [(k
key, v
val)] -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
True k
key v
val
   [(k, v)]
_ -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects a single entry of key-value pair, but got " forall a. [a] -> [a] -> [a]
++ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> Int
V.length Vector (k, v)
avec) forall a. [a] -> [a] -> [a]
++ String
" entries.")
parseToGMapEntry s -> Parser k
kp s -> Parser v
vp (Left KeyMap s
o) = do
  Maybe (GMapEntry k v)
m_ret <- forall s k v.
(s -> Parser k)
-> (s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
parseKeyValueToEntry s -> Parser k
kp s -> Parser v
vp KeyMap s
o forall (m :: * -> *) a.
Monad m =>
m (Maybe a) -> m (Maybe a) -> m (Maybe a)
`orElseM` forall k s v.
FromJSONKey k =>
(s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
parseSingleEntryObjectToEntry s -> Parser v
vp KeyMap s
o
  case Maybe (GMapEntry k v)
m_ret of
   Just GMapEntry k v
ret -> forall (m :: * -> *) a. Monad m => a -> m a
return GMapEntry k v
ret
   Maybe (GMapEntry k v)
Nothing -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Unexpected structure of Object: got keys: " forall a. [a] -> [a] -> [a]
++ (Text -> String
unpack forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
intercalate Text
", " forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Key -> Text
Key.toText forall a b. (a -> b) -> a -> b
$ forall v. KeyMap v -> [Key]
KM.keys KeyMap s
o))

-- | Map to \"g:Map\".
instance GraphSONTyped (GMapEntry k v) where
  gsonTypeFor :: GMapEntry k v -> Text
gsonTypeFor GMapEntry k v
_ = Text
"g:Map"

-- | Use 'parseToGMapEntry'.
instance (FromJSON k, FromJSONKey k, FromJSON v) => FromJSON (GMapEntry k v) where
  parseJSON :: Value -> Parser (GMapEntry k v)
parseJSON Value
val = case Value
val of
    Object Object
o -> Either Object Array -> Parser (GMapEntry k v)
parse forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left Object
o
    Array Array
a  -> Either Object Array -> Parser (GMapEntry k v)
parse forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Array
a
    Value
other    -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Object or Array, but got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Value
other)
    where
      parse :: Either Object Array -> Parser (GMapEntry k v)
parse = forall k s v.
FromJSONKey k =>
(s -> Parser k)
-> (s -> Parser v)
-> Either (KeyMap s) (Vector s)
-> Parser (GMapEntry k v)
parseToGMapEntry forall a. FromJSON a => Value -> Parser a
parseJSON forall a. FromJSON a => Value -> Parser a
parseJSON

instance (ToJSON k, ToJSONKey k, Ord k, ToJSON v) => ToJSON (GMapEntry k v) where
  toJSON :: GMapEntry k v -> Value
toJSON GMapEntry k v
e = forall a. ToJSON a => a -> Value
toJSON forall a b. (a -> b) -> a -> b
$ forall k v. Ord k => GMapEntry k v -> GMap Map k v
singleton' GMapEntry k v
e
    where
      singleton' :: (Ord k) => GMapEntry k v -> GMap M.Map k v
      singleton' :: forall k v. Ord k => GMapEntry k v -> GMap Map k v
singleton' = forall (c :: * -> * -> *) k v.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
GMapEntry k v -> GMap c k v
singleton

-- | Get the key-value pair from 'GMapEntry'.
unGMapEntry :: GMapEntry k v -> (k, v)
unGMapEntry :: forall k v. GMapEntry k v -> (k, v)
unGMapEntry GMapEntry k v
e = (forall k v. GMapEntry k v -> k
gmapEntryKey GMapEntry k v
e, forall k v. GMapEntry k v -> v
gmapEntryValue GMapEntry k v
e)

-- | Create 'GMap' that has the single 'GMapEntry'.
singleton :: (IsList (c k v), Item (c k v) ~ (k,v)) => GMapEntry k v -> GMap c k v
singleton :: forall (c :: * -> * -> *) k v.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
GMapEntry k v -> GMap c k v
singleton GMapEntry k v
e = GMap { gmapFlat :: Bool
gmapFlat = forall k v. GMapEntry k v -> Bool
gmapEntryFlat GMapEntry k v
e,
                     gmapValue :: c k v
gmapValue = forall l. IsList l => [Item l] -> l
List.fromList [(forall k v. GMapEntry k v -> k
gmapEntryKey GMapEntry k v
e, forall k v. GMapEntry k v -> v
gmapEntryValue GMapEntry k v
e)]
                   }

-- | Deconstruct 'GMap' into a list of 'GMapEntry's.
toList :: (IsList (c k v), Item (c k v) ~ (k,v)) => GMap c k v -> [GMapEntry k v]
toList :: forall (c :: * -> * -> *) k v.
(IsList (c k v), Item (c k v) ~ (k, v)) =>
GMap c k v -> [GMapEntry k v]
toList GMap c k v
gm = forall a b. (a -> b) -> [a] -> [b]
map (k, v) -> GMapEntry k v
toEntry forall a b. (a -> b) -> a -> b
$ forall l. IsList l => l -> [Item l]
List.toList forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. GMap c k v -> c k v
gmapValue GMap c k v
gm
  where
    toEntry :: (k, v) -> GMapEntry k v
toEntry (k
k, v
v) = forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry (forall (c :: * -> * -> *) k v. GMap c k v -> Bool
gmapFlat GMap c k v
gm) k
k v
v

-- | Examples of using this module. See the source. The 'fst' of the output is the testee, while the
-- 'snd' is the expectation.
examples :: [(String, String)]
examples :: [(String, String)]
examples = [(String, String)]
forFlattenedMap forall a. [a] -> [a] -> [a]
++ [(String, String)]
forGMap forall a. [a] -> [a] -> [a]
++ [(String, String)]
forGMapEntry
  where
    forFlattenedMap :: [(String, String)]
forFlattenedMap =
      [ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FlattenedMap HashMap Int String -> [(Int, String)]
toSortedList forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (FlattenedMap HashMap Int String)
decode ByteString
"[10, \"ten\", 11, \"eleven\"]", String
"Right [(10,\"ten\"),(11,\"eleven\")]")
      , (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FlattenedMap HashMap Int String -> [(Int, String)]
toSortedList forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (FlattenedMap HashMap Int String)
decode ByteString
"[]", String
"Right []")
      , (ByteString -> String
BSLC.unpack forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
Aeson.encode forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap forall a b. (a -> b) -> a -> b
$ (forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(Int
10, String
"ten")] :: HashMap Int String), String
"[10,\"ten\"]")
      ]
      where
        decode :: ByteString -> Either String (FlattenedMap HashMap Int String)
decode ByteString
s = forall a. FromJSON a => ByteString -> Either String a
Aeson.eitherDecode ByteString
s :: Either String (FlattenedMap HashMap Int String)
        toSortedList :: FlattenedMap HashMap Int String -> [(Int, String)]
toSortedList = forall a. Ord a => [a] -> [a]
sort forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k v. HashMap k v -> [(k, v)]
HashMap.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (c :: * -> * -> *) k v. FlattenedMap c k v -> c k v
unFlattenedMap
    forGMap :: [(String, String)]
forGMap =
      [ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (GMap HashMap Text Int)
decode ByteString
"{\"ten\": 10}", String
"Right (GMap {gmapFlat = False, gmapValue = fromList [(\"ten\",10)]})")
      , (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (GMap HashMap Text Int)
decode ByteString
"[\"ten\", 10]", String
"Right (GMap {gmapFlat = True, gmapValue = fromList [(\"ten\",10)]})")
      , (ByteString -> String
BSLC.unpack forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
Aeson.encode forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
False (forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(Int
9, Text
"nine")] :: HashMap Int Text), String
"{\"9\":\"nine\"}")
      , (ByteString -> String
BSLC.unpack forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
Aeson.encode forall a b. (a -> b) -> a -> b
$ forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
True (forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(Int
9, Text
"nine")] :: HashMap Int Text), String
"[9,\"nine\"]")
      ]
      where
        decode :: ByteString -> Either String (GMap HashMap Text Int)
decode ByteString
s = forall a. FromJSON a => ByteString -> Either String a
Aeson.eitherDecode ByteString
s :: Either String (GMap HashMap Text Int)
    forGMapEntry :: [(String, String)]
forGMapEntry =
      [ (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (GMapEntry Int Text)
decode ByteString
"{\"1\": \"one\"}", String
"Right (GMapEntry {gmapEntryFlat = False, gmapEntryKey = 1, gmapEntryValue = \"one\"})")
      , (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (GMapEntry Int Text)
decode ByteString
"[1, \"one\"]", String
"Right (GMapEntry {gmapEntryFlat = True, gmapEntryKey = 1, gmapEntryValue = \"one\"})")
      , (ByteString -> String
BSLC.unpack forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
Aeson.encode (forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
False Text
"one" Int
1 :: GMapEntry Text Int), String
"{\"one\":1}")
      , (ByteString -> String
BSLC.unpack forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
Aeson.encode (forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
True Text
"one" Int
1 :: GMapEntry Text Int), String
"[\"one\",1]")
      , (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (GMapEntry Int Text)
decode ByteString
"{\"key\":1, \"value\": \"one\"}", String
"Right (GMapEntry {gmapEntryFlat = False, gmapEntryKey = 1, gmapEntryValue = \"one\"})")
      ]
      where
        decode :: ByteString -> Either String (GMapEntry Int Text)
decode ByteString
s = forall a. FromJSON a => ByteString -> Either String a
Aeson.eitherDecode ByteString
s :: Either String (GMapEntry Int Text)