{-# 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
(FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> (FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> Eq (FlattenedMap c k v)
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
$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
/= :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
Eq, (forall m. Monoid m => FlattenedMap c k m -> m)
-> (forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m)
-> (forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m)
-> (forall a b. (a -> b -> b) -> b -> FlattenedMap c k a -> b)
-> (forall a b. (a -> b -> b) -> b -> FlattenedMap c k a -> b)
-> (forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b)
-> (forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b)
-> (forall a. (a -> a -> a) -> FlattenedMap c k a -> a)
-> (forall a. (a -> a -> a) -> FlattenedMap c k a -> a)
-> (forall a. FlattenedMap c k a -> [a])
-> (forall a. FlattenedMap c k a -> Bool)
-> (forall a. FlattenedMap c k a -> Int)
-> (forall a. Eq a => a -> FlattenedMap c k a -> Bool)
-> (forall a. Ord a => FlattenedMap c k a -> a)
-> (forall a. Ord a => FlattenedMap c k a -> a)
-> (forall a. Num a => FlattenedMap c k a -> a)
-> (forall a. Num a => FlattenedMap c k a -> a)
-> Foldable (FlattenedMap c k)
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
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
FlattenedMap c k m -> m
fold :: forall m. Monoid m => FlattenedMap c k m -> 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
foldMap' :: forall m a. Monoid m => (a -> m) -> FlattenedMap c k a -> m
$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
foldr' :: forall a b. (a -> b -> 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
foldl' :: forall b a. (b -> a -> b) -> b -> FlattenedMap c k a -> b
$cfoldr1 :: 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
$cfoldl1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> FlattenedMap c k a -> a
foldl1 :: forall a. (a -> a -> a) -> FlattenedMap c k a -> a
$ctoList :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> [a]
toList :: forall a. FlattenedMap c k a -> [a]
$cnull :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Bool
null :: forall a. FlattenedMap c k a -> Bool
$clength :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Int
length :: forall a. FlattenedMap c k a -> Int
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> FlattenedMap c k a -> Bool
elem :: forall a. Eq a => a -> FlattenedMap c k a -> Bool
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
maximum :: forall a. Ord a => FlattenedMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
minimum :: forall a. Ord a => FlattenedMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
sum :: forall a. Num a => FlattenedMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
product :: forall a. Num a => FlattenedMap c k a -> a
Foldable, (forall a b. (a -> b) -> FlattenedMap c k a -> FlattenedMap c k b)
-> (forall a b. a -> FlattenedMap c k b -> FlattenedMap c k a)
-> Functor (FlattenedMap c k)
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
$cfmap :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
fmap :: forall a b. (a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
$c<$ :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> FlattenedMap c k b -> FlattenedMap c k a
<$ :: forall a b. a -> FlattenedMap c k b -> FlattenedMap c k a
Functor, Eq (FlattenedMap c k v)
Eq (FlattenedMap c k v) =>
(FlattenedMap c k v -> FlattenedMap c k v -> Ordering)
-> (FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> (FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> (FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> (FlattenedMap c k v -> FlattenedMap c k v -> Bool)
-> (FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v)
-> (FlattenedMap c k v -> FlattenedMap c k v -> FlattenedMap c k v)
-> Ord (FlattenedMap c k v)
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
$ccompare :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
FlattenedMap c k v -> FlattenedMap c k v -> Ordering
compare :: FlattenedMap c k v -> FlattenedMap c k v -> Ordering
$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
>= :: FlattenedMap c k v -> FlattenedMap c k v -> Bool
$cmax :: 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
$cmin :: 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
Ord, Int -> FlattenedMap c k v -> ShowS
[FlattenedMap c k v] -> ShowS
FlattenedMap c k v -> String
(Int -> FlattenedMap c k v -> ShowS)
-> (FlattenedMap c k v -> String)
-> ([FlattenedMap c k v] -> ShowS)
-> Show (FlattenedMap c k v)
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
$cshowsPrec :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> FlattenedMap c k v -> ShowS
showsPrec :: Int -> FlattenedMap c k v -> ShowS
$cshow :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
FlattenedMap c k v -> String
show :: FlattenedMap c k v -> String
$cshowList :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
[FlattenedMap c k v] -> ShowS
showList :: [FlattenedMap c k v] -> ShowS
Show, Functor (FlattenedMap c k)
Foldable (FlattenedMap c k)
(Functor (FlattenedMap c k), Foldable (FlattenedMap c k)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    FlattenedMap c k (f a) -> f (FlattenedMap c k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b))
-> (forall (m :: * -> *) a.
    Monad m =>
    FlattenedMap c k (m a) -> m (FlattenedMap c k a))
-> Traversable (FlattenedMap c k)
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 (m :: * -> *) a.
Monad m =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
forall (f :: * -> *) a.
Applicative f =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
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)
$ctraverse :: forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c k b)
$csequenceA :: forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
FlattenedMap c k (f a) -> f (FlattenedMap c k a)
$cmapM :: forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> FlattenedMap c k a -> m (FlattenedMap c k b)
$csequence :: forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
sequence :: forall (m :: * -> *) a.
Monad m =>
FlattenedMap c k (m a) -> m (FlattenedMap c k a)
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) = (Value -> Parser k)
-> (Value -> Parser v) -> Array -> Parser (FlattenedMap c k 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 Value -> Parser k
forall a. FromJSON a => Value -> Parser a
parseJSON Value -> Parser v
forall a. FromJSON a => Value -> Parser a
parseJSON Array
v
  parseJSON Value
v         = String -> Parser (FlattenedMap c k v)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Array, but got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
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 Int -> Bool
forall a. Integral a => a -> Bool
odd Int
vlen
  then String -> Parser (Vector (k, v))
forall a. String -> Parser a
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 ((s, s) -> Parser (k, v))
-> Vector (s, s) -> Parser (Vector (k, v))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Vector a -> f (Vector b)
traverse (s, s) -> Parser (k, v)
parsePair Vector (s, s)
pairVec
  where
    vlen :: Int
vlen = Vector s -> Int
forall a. Vector a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector s
v
    pairVec :: Vector (s, s)
pairVec = (Int -> (s, s)) -> Vector Int -> Vector (s, s)
forall a b. (a -> b) -> Vector a -> Vector b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Int
i -> (Vector s
v Vector s -> Int -> s
forall a. Vector a -> Int -> a
! (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2), Vector s
v Vector s -> Int -> s
forall a. Vector a -> Int -> a
! (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) (Vector Int -> Vector (s, s)) -> Vector Int -> Vector (s, s)
forall a b. (a -> b) -> a -> b
$ [Int] -> Vector Int
forall a. [a] -> Vector a
V.fromList [Int
0 .. ((Int
vlen Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)]
    parsePair :: (s, s) -> Parser (k, v)
parsePair (s
vk, s
vv) = (,) (k -> v -> (k, v)) -> Parser k -> Parser (v -> (k, v))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> Parser k
parseKey s
vk Parser (v -> (k, v)) -> Parser v -> Parser (k, v)
forall a b. Parser (a -> b) -> Parser a -> Parser b
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 =
  (Vector (k, v) -> FlattenedMap c k v)
-> Parser (Vector (k, v)) -> Parser (FlattenedMap c k v)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (c k v -> FlattenedMap c k v
forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap (c k v -> FlattenedMap c k v)
-> (Vector (k, v) -> c k v) -> Vector (k, v) -> FlattenedMap c k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(k, v)] -> c k v
[Item (c k v)] -> c k v
forall l. IsList l => [Item l] -> l
List.fromList ([(k, v)] -> c k v)
-> (Vector (k, v) -> [(k, v)]) -> Vector (k, v) -> c k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (k, v) -> [(k, v)]
forall a. Vector a -> [a]
V.toList) (Parser (Vector (k, v)) -> Parser (FlattenedMap c k v))
-> Parser (Vector (k, v)) -> Parser (FlattenedMap c k v)
forall a b. (a -> b) -> a -> b
$ (s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (Vector (k, v))
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) = [Value] -> Value
forall a. ToJSON a => a -> Value
toJSON ([Value] -> Value) -> [Value] -> Value
forall a b. (a -> b) -> a -> b
$ [(Value, Value)] -> [Value]
forall {b}. [(b, b)] -> [b]
flatten ([(Value, Value)] -> [Value]) -> [(Value, Value)] -> [Value]
forall a b. (a -> b) -> a -> b
$ ((k, v) -> (Value, Value)) -> [(k, v)] -> [(Value, Value)]
forall a b. (a -> b) -> [a] -> [b]
map (k, v) -> (Value, Value)
forall {a} {a}. (ToJSON a, ToJSON a) => (a, a) -> (Value, Value)
toValuePair ([(k, v)] -> [(Value, Value)]) -> [(k, v)] -> [(Value, Value)]
forall a b. (a -> b) -> a -> b
$ c k v -> [Item (c k v)]
forall l. IsList l => l -> [Item l]
List.toList c k v
m
    where
      toValuePair :: (a, a) -> (Value, Value)
toValuePair (a
k, a
v) = (a -> Value
forall a. ToJSON a => a -> Value
toJSON a
k, a -> Value
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]) ((b, b) -> [b]) -> [(b, b)] -> [b]
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
(GMap c k v -> GMap c k v -> Bool)
-> (GMap c k v -> GMap c k v -> Bool) -> Eq (GMap c k v)
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
$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
/= :: GMap c k v -> GMap c k v -> Bool
Eq, (forall m. Monoid m => GMap c k m -> m)
-> (forall m a. Monoid m => (a -> m) -> GMap c k a -> m)
-> (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 a b. (a -> b -> b) -> b -> GMap c k a -> b)
-> (forall b a. (b -> a -> b) -> b -> GMap c k a -> b)
-> (forall b a. (b -> a -> b) -> b -> GMap c k a -> b)
-> (forall a. (a -> a -> a) -> GMap c k a -> a)
-> (forall a. (a -> a -> a) -> GMap c k a -> a)
-> (forall a. GMap c k a -> [a])
-> (forall a. GMap c k a -> Bool)
-> (forall a. GMap c k a -> Int)
-> (forall a. Eq a => a -> GMap c k a -> Bool)
-> (forall a. Ord a => GMap c k a -> a)
-> (forall a. Ord a => GMap c k a -> a)
-> (forall a. Num a => GMap c k a -> a)
-> (forall a. Num a => GMap c k a -> a)
-> Foldable (GMap c k)
forall a. Eq a => a -> GMap c k a -> Bool
forall a. Num a => GMap c k a -> a
forall a. Ord a => GMap c k a -> a
forall m. Monoid m => GMap c k m -> m
forall a. GMap c k a -> Bool
forall a. GMap c k a -> Int
forall a. GMap c k a -> [a]
forall a. (a -> a -> a) -> GMap c k a -> a
forall m a. Monoid m => (a -> m) -> GMap c k a -> m
forall b a. (b -> a -> b) -> b -> GMap c k a -> b
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
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
GMap c k m -> m
fold :: forall m. Monoid m => GMap c k m -> 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
foldMap' :: forall m a. Monoid m => (a -> m) -> GMap c k a -> m
$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
foldr' :: forall a b. (a -> b -> 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
foldl' :: forall b a. (b -> a -> b) -> b -> GMap c k a -> b
$cfoldr1 :: 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
$cfoldl1 :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
(a -> a -> a) -> GMap c k a -> a
foldl1 :: forall a. (a -> a -> a) -> GMap c k a -> a
$ctoList :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> [a]
toList :: forall a. GMap c k a -> [a]
$cnull :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Bool
null :: forall a. GMap c k a -> Bool
$clength :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Int
length :: forall a. GMap c k a -> Int
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> GMap c k a -> Bool
elem :: forall a. Eq a => a -> GMap c k a -> Bool
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
maximum :: forall a. Ord a => GMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
minimum :: forall a. Ord a => GMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
sum :: forall a. Num a => GMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
product :: forall a. Num a => GMap c k a -> a
Foldable, (forall a b. (a -> b) -> GMap c k a -> GMap c k b)
-> (forall a b. a -> GMap c k b -> GMap c k a)
-> Functor (GMap c k)
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
$cfmap :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
(a -> b) -> GMap c k a -> GMap c k b
fmap :: forall a b. (a -> b) -> GMap c k a -> GMap c k b
$c<$ :: forall (c :: * -> * -> *) k a b.
Functor (c k) =>
a -> GMap c k b -> GMap c k a
<$ :: forall a b. a -> GMap c k b -> GMap c k a
Functor, Int -> GMap c k v -> ShowS
[GMap c k v] -> ShowS
GMap c k v -> String
(Int -> GMap c k v -> ShowS)
-> (GMap c k v -> String)
-> ([GMap c k v] -> ShowS)
-> Show (GMap c k v)
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
$cshowsPrec :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
Int -> GMap c k v -> ShowS
showsPrec :: Int -> GMap c k v -> ShowS
$cshow :: forall (c :: * -> * -> *) k v. Show (c k v) => GMap c k v -> String
show :: GMap c k v -> String
$cshowList :: forall (c :: * -> * -> *) k v.
Show (c k v) =>
[GMap c k v] -> ShowS
showList :: [GMap c k v] -> ShowS
Show, Functor (GMap c k)
Foldable (GMap c k)
(Functor (GMap c k), Foldable (GMap c k)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> GMap c k a -> f (GMap c k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    GMap c k (f a) -> f (GMap c k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> GMap c k a -> m (GMap c k b))
-> (forall (m :: * -> *) a.
    Monad m =>
    GMap c k (m a) -> m (GMap c k a))
-> Traversable (GMap c k)
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 (m :: * -> *) a. Monad m => GMap c k (m a) -> m (GMap c k a)
forall (f :: * -> *) a.
Applicative f =>
GMap c k (f a) -> f (GMap c k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
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)
$ctraverse :: forall (c :: * -> * -> *) k (f :: * -> *) a b.
(Traversable (c k), Applicative f) =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMap c k a -> f (GMap c k b)
$csequenceA :: forall (c :: * -> * -> *) k (f :: * -> *) a.
(Traversable (c k), Applicative f) =>
GMap c k (f a) -> f (GMap c k a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
GMap c k (f a) -> f (GMap c k a)
$cmapM :: forall (c :: * -> * -> *) k (m :: * -> *) a b.
(Traversable (c k), Monad m) =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMap c k a -> m (GMap c k b)
$csequence :: forall (c :: * -> * -> *) k (m :: * -> *) a.
(Traversable (c k), Monad m) =>
GMap c k (m a) -> m (GMap c k a)
sequence :: forall (m :: * -> *) a. Monad m => GMap c k (m a) -> m (GMap c k a)
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)   = (c k v -> GMap c k v) -> Parser (c k v) -> Parser (GMap c k v)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> c k v -> GMap c k v
forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
False) (Parser (c k v) -> Parser (GMap c k v))
-> Parser (c k v) -> Parser (GMap c k v)
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) = (FlattenedMap c k v -> GMap c k v)
-> Parser (FlattenedMap c k v) -> Parser (GMap c k v)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> c k v -> GMap c k v
forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
True (c k v -> GMap c k v)
-> (FlattenedMap c k v -> c k v)
-> FlattenedMap c k v
-> GMap c k v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FlattenedMap c k v -> c k v
forall (c :: * -> * -> *) k v. FlattenedMap c k v -> c k v
unFlattenedMap) (Parser (FlattenedMap c k v) -> Parser (GMap c k v))
-> Parser (FlattenedMap c k v) -> Parser (GMap c k v)
forall a b. (a -> b) -> a -> b
$ (s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (FlattenedMap c k 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 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 (Either Object Array -> Parser (GMap c k v))
-> Either Object Array -> Parser (GMap c k v)
forall a b. (a -> b) -> a -> b
$ Object -> Either Object Array
forall a b. a -> Either a b
Left Object
o
    Array Array
a  -> Either Object Array -> Parser (GMap c k v)
parse (Either Object Array -> Parser (GMap c k v))
-> Either Object Array -> Parser (GMap c k v)
forall a b. (a -> b) -> a -> b
$ Array -> Either Object Array
forall a b. b -> Either a b
Right Array
a
    Value
other    -> String -> Parser (GMap c k v)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Object or Array, but got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
other)
    where
      parse :: Either Object Array -> Parser (GMap c k v)
parse = (Value -> Parser k)
-> (Value -> Parser v)
-> (Object -> Parser (c k v))
-> Either Object Array
-> Parser (GMap c k v)
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 Value -> Parser k
forall a. FromJSON a => Value -> Parser a
parseJSON Value -> Parser v
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser (c k v)
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser (c k v))
-> (Object -> Value) -> Object -> Parser (c k v)
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 GMap c k v -> Bool
forall (c :: * -> * -> *) k v. GMap c k v -> Bool
gmapFlat GMap c k v
gm
              then FlattenedMap c k v -> Value
forall a. ToJSON a => a -> Value
toJSON (FlattenedMap c k v -> Value) -> FlattenedMap c k v -> Value
forall a b. (a -> b) -> a -> b
$ c k v -> FlattenedMap c k v
forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap (c k v -> FlattenedMap c k v) -> c k v -> FlattenedMap c k v
forall a b. (a -> b) -> a -> b
$ GMap c k v -> c k v
forall (c :: * -> * -> *) k v. GMap c k v -> c k v
unGMap GMap c k v
gm
              else c k v -> Value
forall a. ToJSON a => a -> Value
toJSON (c k v -> Value) -> c k v -> Value
forall a b. (a -> b) -> a -> b
$ GMap c k v -> c k v
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 = GMap c k v -> c k v
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
(GMapEntry k v -> GMapEntry k v -> Bool)
-> (GMapEntry k v -> GMapEntry k v -> Bool) -> Eq (GMapEntry k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v. (Eq k, Eq v) => 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
/= :: GMapEntry k v -> GMapEntry k v -> Bool
Eq, (forall m. Monoid m => GMapEntry k m -> m)
-> (forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m)
-> (forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m)
-> (forall a b. (a -> b -> b) -> b -> GMapEntry k a -> b)
-> (forall a b. (a -> b -> b) -> b -> GMapEntry k a -> b)
-> (forall b a. (b -> a -> b) -> b -> GMapEntry k a -> b)
-> (forall b a. (b -> a -> b) -> b -> GMapEntry k a -> b)
-> (forall a. (a -> a -> a) -> GMapEntry k a -> a)
-> (forall a. (a -> a -> a) -> GMapEntry k a -> a)
-> (forall a. GMapEntry k a -> [a])
-> (forall a. GMapEntry k a -> Bool)
-> (forall a. GMapEntry k a -> Int)
-> (forall a. Eq a => a -> GMapEntry k a -> Bool)
-> (forall a. Ord a => GMapEntry k a -> a)
-> (forall a. Ord a => GMapEntry k a -> a)
-> (forall a. Num a => GMapEntry k a -> a)
-> (forall a. Num a => GMapEntry k a -> a)
-> Foldable (GMapEntry k)
forall a. Eq a => a -> GMapEntry k a -> Bool
forall a. Num a => GMapEntry k a -> a
forall a. Ord a => GMapEntry k a -> a
forall m. Monoid m => GMapEntry k m -> m
forall a. GMapEntry k a -> Bool
forall a. GMapEntry k a -> Int
forall a. GMapEntry k a -> [a]
forall a. (a -> a -> a) -> GMapEntry k a -> a
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 b a. (b -> a -> b) -> b -> GMapEntry k a -> b
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
$cfold :: forall k m. Monoid m => GMapEntry k m -> m
fold :: forall m. Monoid m => GMapEntry k m -> 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
foldMap' :: forall m a. Monoid m => (a -> m) -> GMapEntry k a -> m
$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
foldr' :: forall a b. (a -> b -> 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
foldl' :: forall b a. (b -> a -> b) -> b -> GMapEntry k a -> b
$cfoldr1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldr1 :: forall a. (a -> a -> a) -> GMapEntry k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldl1 :: forall a. (a -> a -> a) -> GMapEntry k a -> a
$ctoList :: forall k a. GMapEntry k a -> [a]
toList :: forall a. GMapEntry k a -> [a]
$cnull :: forall k v. GMapEntry k v -> Bool
null :: forall a. GMapEntry k a -> Bool
$clength :: forall k a. GMapEntry k a -> Int
length :: forall a. GMapEntry k a -> Int
$celem :: forall k a. Eq a => a -> GMapEntry k a -> Bool
elem :: forall a. Eq a => a -> GMapEntry k a -> Bool
$cmaximum :: forall k a. Ord a => GMapEntry k a -> a
maximum :: forall a. Ord a => GMapEntry k a -> a
$cminimum :: forall k a. Ord a => GMapEntry k a -> a
minimum :: forall a. Ord a => GMapEntry k a -> a
$csum :: forall k a. Num a => GMapEntry k a -> a
sum :: forall a. Num a => GMapEntry k a -> a
$cproduct :: forall k a. Num a => GMapEntry k a -> a
product :: forall a. Num a => GMapEntry k a -> a
Foldable, (forall a b. (a -> b) -> GMapEntry k a -> GMapEntry k b)
-> (forall a b. a -> GMapEntry k b -> GMapEntry k a)
-> Functor (GMapEntry k)
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
$cfmap :: forall k a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
fmap :: forall a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
$c<$ :: forall k a b. a -> GMapEntry k b -> GMapEntry k a
<$ :: forall a b. a -> GMapEntry k b -> GMapEntry k a
Functor, Eq (GMapEntry k v)
Eq (GMapEntry k v) =>
(GMapEntry k v -> GMapEntry k v -> Ordering)
-> (GMapEntry k v -> GMapEntry k v -> Bool)
-> (GMapEntry k v -> GMapEntry k v -> Bool)
-> (GMapEntry k v -> GMapEntry k v -> Bool)
-> (GMapEntry k v -> GMapEntry k v -> Bool)
-> (GMapEntry k v -> GMapEntry k v -> GMapEntry k v)
-> (GMapEntry k v -> GMapEntry k v -> GMapEntry k v)
-> Ord (GMapEntry k v)
GMapEntry k v -> GMapEntry k v -> Bool
GMapEntry k v -> GMapEntry k v -> Ordering
GMapEntry k v -> GMapEntry k v -> GMapEntry 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 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
$ccompare :: forall k v.
(Ord k, Ord v) =>
GMapEntry k v -> GMapEntry k v -> Ordering
compare :: GMapEntry k v -> GMapEntry k v -> Ordering
$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
>= :: GMapEntry k v -> GMapEntry k v -> Bool
$cmax :: 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
$cmin :: 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
Ord, Int -> GMapEntry k v -> ShowS
[GMapEntry k v] -> ShowS
GMapEntry k v -> String
(Int -> GMapEntry k v -> ShowS)
-> (GMapEntry k v -> String)
-> ([GMapEntry k v] -> ShowS)
-> Show (GMapEntry k v)
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
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> GMapEntry k v -> ShowS
showsPrec :: Int -> GMapEntry k v -> ShowS
$cshow :: forall k v. (Show k, Show v) => GMapEntry k v -> String
show :: GMapEntry k v -> String
$cshowList :: forall k v. (Show k, Show v) => [GMapEntry k v] -> ShowS
showList :: [GMapEntry k v] -> ShowS
Show, Functor (GMapEntry k)
Foldable (GMapEntry k)
(Functor (GMapEntry k), Foldable (GMapEntry k)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> GMapEntry k a -> f (GMapEntry k b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    GMapEntry k (f a) -> f (GMapEntry k a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> GMapEntry k a -> m (GMapEntry k b))
-> (forall (m :: * -> *) a.
    Monad m =>
    GMapEntry k (m a) -> m (GMapEntry k a))
-> Traversable (GMapEntry k)
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 (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
forall (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
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)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
$csequenceA :: forall k (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
$cmapM :: forall k (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> GMapEntry k a -> m (GMapEntry k b)
$csequence :: forall k (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
sequence :: forall (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
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 KeyMap s -> Int
forall a. KeyMap a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length KeyMap s
o Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
2
  then Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (GMapEntry k v)
forall a. Maybe a
Nothing
  else do
    Maybe k
mk <- (s -> Parser k) -> Maybe s -> Parser (Maybe k)
forall a v. (a -> Parser v) -> Maybe a -> Parser (Maybe v)
parseIfPresent s -> Parser k
kp (Maybe s -> Parser (Maybe k)) -> Maybe s -> Parser (Maybe k)
forall a b. (a -> b) -> a -> b
$ Key -> KeyMap s -> Maybe s
forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"key" KeyMap s
o
    Maybe v
mv <- (s -> Parser v) -> Maybe s -> Parser (Maybe v)
forall a v. (a -> Parser v) -> Maybe a -> Parser (Maybe v)
parseIfPresent s -> Parser v
vp (Maybe s -> Parser (Maybe v)) -> Maybe s -> Parser (Maybe v)
forall a b. (a -> b) -> a -> b
$ Key -> KeyMap s -> Maybe s
forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
"value" KeyMap s
o
    Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v)))
-> Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a b. (a -> b) -> a -> b
$ Bool -> k -> v -> GMapEntry k v
forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
False (k -> v -> GMapEntry k v) -> Maybe k -> Maybe (v -> GMapEntry k v)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe k
mk Maybe (v -> GMapEntry k v) -> Maybe v -> Maybe (GMapEntry k v)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
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 = Parser (Maybe v)
-> (a -> Parser (Maybe v)) -> Maybe a -> Parser (Maybe v)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe v -> Parser (Maybe v)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe v
forall a. Maybe a
Nothing) ((v -> Maybe v) -> Parser v -> Parser (Maybe v)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap v -> Maybe v
forall a. a -> Maybe a
Just (Parser v -> Parser (Maybe v))
-> (a -> Parser v) -> a -> Parser (Maybe v)
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 KeyMap s -> [(Key, s)]
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 (Text -> Parser k) -> Text -> Parser k
forall a b. (a -> b) -> a -> b
$ Key -> Text
Key.toText Key
raw_key
     v
val <- s -> Parser v
vp s
raw_val
     Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v)))
-> Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a b. (a -> b) -> a -> b
$ GMapEntry k v -> Maybe (GMapEntry k v)
forall a. a -> Maybe a
Just (GMapEntry k v -> Maybe (GMapEntry k v))
-> GMapEntry k v -> Maybe (GMapEntry k v)
forall a b. (a -> b) -> a -> b
$ Bool -> k -> v -> GMapEntry k v
forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
False k
key v
val
   [(Key, s)]
_ -> Maybe (GMapEntry k v) -> Parser (Maybe (GMapEntry k v))
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (GMapEntry k v)
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 FromJSONKeyFunction k
forall a. FromJSONKey a => FromJSONKeyFunction a
fromJSONKey of
      FromJSONKeyText Text -> k
p -> (Text -> Parser k) -> Parser (Text -> Parser k)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text -> Parser k) -> Parser (Text -> Parser k))
-> (Text -> Parser k) -> Parser (Text -> Parser k)
forall a b. (a -> b) -> a -> b
$ (k -> Parser k) -> (Text -> k) -> Text -> Parser k
forall a b. (a -> b) -> (Text -> a) -> Text -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Parser k
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Text -> k
p
      FromJSONKeyTextParser Text -> Parser k
p -> (Text -> Parser k) -> Parser (Text -> Parser k)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Text -> Parser k
p
      FromJSONKeyValue Value -> Parser k
_ -> String -> Parser (Text -> Parser k)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ( String
"Unexpected FromJSONKeyValue."
                                   String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" It expects that the entry key is parsed from the text key in JSON Object,"
                                   String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" but the key type does not support it."
                                 )
      FromJSONKeyFunction k
FromJSONKeyCoerce -> (Text -> Parser k) -> Parser (Text -> Parser k)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text -> Parser k) -> Parser (Text -> Parser k))
-> (Text -> Parser k) -> Parser (Text -> Parser k)
forall a b. (a -> b) -> a -> b
$ (k -> Parser k) -> (Text -> k) -> Text -> Parser k
forall a b. (a -> b) -> (Text -> a) -> Text -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Parser k
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Text -> k
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  -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
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 <- (s -> Parser k)
-> (s -> Parser v) -> Vector s -> Parser (Vector (k, v))
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 Vector (k, v) -> [(k, v)]
forall a. Vector a -> [a]
V.toList Vector (k, v)
avec of
   [(k
key, v
val)] -> GMapEntry k v -> Parser (GMapEntry k v)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (GMapEntry k v -> Parser (GMapEntry k v))
-> GMapEntry k v -> Parser (GMapEntry k v)
forall a b. (a -> b) -> a -> b
$ Bool -> k -> v -> GMapEntry k v
forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
True k
key v
val
   [(k, v)]
_ -> String -> Parser (GMapEntry k v)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects a single entry of key-value pair, but got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ Vector (k, v) -> Int
forall a. Vector a -> Int
V.length Vector (k, v)
avec) String -> ShowS
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 <- (s -> Parser k)
-> (s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
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 Parser (Maybe (GMapEntry k v))
-> Parser (Maybe (GMapEntry k v)) -> Parser (Maybe (GMapEntry k v))
forall (m :: * -> *) a.
Monad m =>
m (Maybe a) -> m (Maybe a) -> m (Maybe a)
`orElseM` (s -> Parser v) -> KeyMap s -> Parser (Maybe (GMapEntry k v))
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 -> GMapEntry k v -> Parser (GMapEntry k v)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return GMapEntry k v
ret
   Maybe (GMapEntry k v)
Nothing -> String -> Parser (GMapEntry k v)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Unexpected structure of Object: got keys: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
intercalate Text
", " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Key -> Text) -> [Key] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Key -> Text
Key.toText ([Key] -> [Text]) -> [Key] -> [Text]
forall a b. (a -> b) -> a -> b
$ KeyMap s -> [Key]
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 (Either Object Array -> Parser (GMapEntry k v))
-> Either Object Array -> Parser (GMapEntry k v)
forall a b. (a -> b) -> a -> b
$ Object -> Either Object Array
forall a b. a -> Either a b
Left Object
o
    Array Array
a  -> Either Object Array -> Parser (GMapEntry k v)
parse (Either Object Array -> Parser (GMapEntry k v))
-> Either Object Array -> Parser (GMapEntry k v)
forall a b. (a -> b) -> a -> b
$ Array -> Either Object Array
forall a b. b -> Either a b
Right Array
a
    Value
other    -> String -> Parser (GMapEntry k v)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Expects Object or Array, but got " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
other)
    where
      parse :: Either Object Array -> Parser (GMapEntry k v)
parse = (Value -> Parser k)
-> (Value -> Parser v)
-> Either Object Array
-> Parser (GMapEntry k v)
forall k s v.
FromJSONKey k =>
(s -> Parser k)
-> (s -> Parser v)
-> Either (KeyMap s) (Vector s)
-> Parser (GMapEntry k v)
parseToGMapEntry Value -> Parser k
forall a. FromJSON a => Value -> Parser a
parseJSON Value -> Parser v
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 = GMap Map k v -> Value
forall a. ToJSON a => a -> Value
toJSON (GMap Map k v -> Value) -> GMap Map k v -> Value
forall a b. (a -> b) -> a -> b
$ GMapEntry k v -> GMap Map k v
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' = GMapEntry k v -> GMap Map k v
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 = (GMapEntry k v -> k
forall k v. GMapEntry k v -> k
gmapEntryKey GMapEntry k v
e, GMapEntry k v -> v
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 = GMapEntry k v -> Bool
forall k v. GMapEntry k v -> Bool
gmapEntryFlat GMapEntry k v
e,
                     gmapValue :: c k v
gmapValue = [Item (c k v)] -> c k v
forall l. IsList l => [Item l] -> l
List.fromList [(GMapEntry k v -> k
forall k v. GMapEntry k v -> k
gmapEntryKey GMapEntry k v
e, GMapEntry k v -> v
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 = ((k, v) -> GMapEntry k v) -> [(k, v)] -> [GMapEntry k v]
forall a b. (a -> b) -> [a] -> [b]
map (k, v) -> GMapEntry k v
toEntry ([(k, v)] -> [GMapEntry k v]) -> [(k, v)] -> [GMapEntry k v]
forall a b. (a -> b) -> a -> b
$ c k v -> [Item (c k v)]
forall l. IsList l => l -> [Item l]
List.toList (c k v -> [Item (c k v)]) -> c k v -> [Item (c k v)]
forall a b. (a -> b) -> a -> b
$ GMap c k v -> c k v
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) = Bool -> k -> v -> GMapEntry k v
forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry (GMap c k v -> Bool
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 [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
forGMap [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
forGMapEntry
  where
    forFlattenedMap :: [(String, String)]
forFlattenedMap =
      [ (Either String [(Int, String)] -> String
forall a. Show a => a -> String
show (Either String [(Int, String)] -> String)
-> Either String [(Int, String)] -> String
forall a b. (a -> b) -> a -> b
$ (FlattenedMap HashMap Int String -> [(Int, String)])
-> Either String (FlattenedMap HashMap Int String)
-> Either String [(Int, String)]
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FlattenedMap HashMap Int String -> [(Int, String)]
toSortedList (Either String (FlattenedMap HashMap Int String)
 -> Either String [(Int, String)])
-> Either String (FlattenedMap HashMap Int String)
-> Either String [(Int, String)]
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\")]")
      , (Either String [(Int, String)] -> String
forall a. Show a => a -> String
show (Either String [(Int, String)] -> String)
-> Either String [(Int, String)] -> String
forall a b. (a -> b) -> a -> b
$ (FlattenedMap HashMap Int String -> [(Int, String)])
-> Either String (FlattenedMap HashMap Int String)
-> Either String [(Int, String)]
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FlattenedMap HashMap Int String -> [(Int, String)]
toSortedList (Either String (FlattenedMap HashMap Int String)
 -> Either String [(Int, String)])
-> Either String (FlattenedMap HashMap Int String)
-> Either String [(Int, String)]
forall a b. (a -> b) -> a -> b
$ ByteString -> Either String (FlattenedMap HashMap Int String)
decode ByteString
"[]", String
"Right []")
      , (ByteString -> String
BSLC.unpack (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ FlattenedMap HashMap Int String -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (FlattenedMap HashMap Int String -> ByteString)
-> FlattenedMap HashMap Int String -> ByteString
forall a b. (a -> b) -> a -> b
$ HashMap Int String -> FlattenedMap HashMap Int String
forall (c :: * -> * -> *) k v. c k v -> FlattenedMap c k v
FlattenedMap (HashMap Int String -> FlattenedMap HashMap Int String)
-> HashMap Int String -> FlattenedMap HashMap Int String
forall a b. (a -> b) -> a -> b
$ ([(Int, String)] -> HashMap Int String
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 = ByteString -> Either String (FlattenedMap HashMap Int String)
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 = [(Int, String)] -> [(Int, String)]
forall a. Ord a => [a] -> [a]
sort ([(Int, String)] -> [(Int, String)])
-> (FlattenedMap HashMap Int String -> [(Int, String)])
-> FlattenedMap HashMap Int String
-> [(Int, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap Int String -> [(Int, String)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (HashMap Int String -> [(Int, String)])
-> (FlattenedMap HashMap Int String -> HashMap Int String)
-> FlattenedMap HashMap Int String
-> [(Int, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FlattenedMap HashMap Int String -> HashMap Int String
forall (c :: * -> * -> *) k v. FlattenedMap c k v -> c k v
unFlattenedMap
    forGMap :: [(String, String)]
forGMap =
      [ (Either String (GMap HashMap Text Int) -> String
forall a. Show a => a -> String
show (Either String (GMap HashMap Text Int) -> String)
-> Either String (GMap HashMap Text Int) -> String
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)]})")
      , (Either String (GMap HashMap Text Int) -> String
forall a. Show a => a -> String
show (Either String (GMap HashMap Text Int) -> String)
-> Either String (GMap HashMap Text Int) -> String
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 (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ GMap HashMap Int Text -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (GMap HashMap Int Text -> ByteString)
-> GMap HashMap Int Text -> ByteString
forall a b. (a -> b) -> a -> b
$ Bool -> HashMap Int Text -> GMap HashMap Int Text
forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
False ([(Int, Text)] -> HashMap Int Text
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 (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ GMap HashMap Int Text -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (GMap HashMap Int Text -> ByteString)
-> GMap HashMap Int Text -> ByteString
forall a b. (a -> b) -> a -> b
$ Bool -> HashMap Int Text -> GMap HashMap Int Text
forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap Bool
True ([(Int, Text)] -> HashMap Int Text
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 = ByteString -> Either String (GMap HashMap Text Int)
forall a. FromJSON a => ByteString -> Either String a
Aeson.eitherDecode ByteString
s :: Either String (GMap HashMap Text Int)
    forGMapEntry :: [(String, String)]
forGMapEntry =
      [ (Either String (GMapEntry Int Text) -> String
forall a. Show a => a -> String
show (Either String (GMapEntry Int Text) -> String)
-> Either String (GMapEntry Int Text) -> String
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\"})")
      , (Either String (GMapEntry Int Text) -> String
forall a. Show a => a -> String
show (Either String (GMapEntry Int Text) -> String)
-> Either String (GMapEntry Int Text) -> String
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 (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ GMapEntry Text Int -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (Bool -> Text -> Int -> GMapEntry Text Int
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 (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ GMapEntry Text Int -> ByteString
forall a. ToJSON a => a -> ByteString
Aeson.encode (Bool -> Text -> Int -> GMapEntry Text Int
forall k v. Bool -> k -> v -> GMapEntry k v
GMapEntry Bool
True Text
"one" Int
1 :: GMapEntry Text Int), String
"[\"one\",1]")
      , (Either String (GMapEntry Int Text) -> String
forall a. Show a => a -> String
show (Either String (GMapEntry Int Text) -> String)
-> Either String (GMapEntry Int Text) -> String
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 = ByteString -> Either String (GMapEntry Int Text)
forall a. FromJSON a => ByteString -> Either String a
Aeson.eitherDecode ByteString
s :: Either String (GMapEntry Int Text)