{-# LANGUAGE TypeFamilies, OverloadedStrings, GeneralizedNewtypeDeriving, DeriveTraversable, CPP #-}
-- |
-- 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
       ) where

import Control.Applicative ((<$>), (<*>), (<|>), empty)
import Data.Aeson
  ( FromJSON(..), ToJSON(..), Value(..),
    FromJSONKey, fromJSONKey, FromJSONKeyFunction(..), ToJSONKey
  )
import Data.Aeson.Types (Parser)
import Data.Aeson.KeyMap (KeyMap)
import qualified Data.Aeson.KeyMap as KM
import qualified Data.Aeson.Key as Key
import Data.Foldable (length, Foldable)
import Data.Hashable (Hashable)
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(..))

-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import qualified Data.Aeson as Aeson
-- >>> import Data.HashMap.Strict (HashMap)
-- >>> import qualified Data.HashMap.Strict as HashMap
-- >>> import Data.List (sort)
-- >>> import Data.Either (isLeft)

-- | 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.
--
-- >>> let decode s = Aeson.eitherDecode s :: Either String (FlattenedMap HashMap Int String)
-- >>> let toSortedList = sort . HashMap.toList . unFlattenedMap
-- >>> fmap toSortedList $ decode "[10, \"ten\", 11, \"eleven\"]"
-- Right [(10,"ten"),(11,"eleven")]
-- >>> fmap toSortedList $ decode "[]"
-- Right []
-- >>> let (Left err_msg) = decode "[10, \"ten\", 11]"
-- >>> err_msg
-- ...odd number of elements...
-- >>> Aeson.encode $ FlattenedMap $ (HashMap.fromList [(10, "ten")] :: HashMap Int String)
-- "[10,\"ten\"]"
newtype FlattenedMap c k v = FlattenedMap { FlattenedMap c k v -> c k v
unFlattenedMap :: c k v }
                   deriving (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
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,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
/= :: 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,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
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
$cp1Ord :: forall (c :: * -> * -> *) k v.
Ord (c k v) =>
Eq (FlattenedMap c k v)
Ord,a -> FlattenedMap c k a -> Bool
FlattenedMap c k m -> m
FlattenedMap c k a -> [a]
FlattenedMap c k a -> Bool
FlattenedMap c k a -> Int
FlattenedMap c k a -> a
FlattenedMap c k a -> a
FlattenedMap c k a -> a
FlattenedMap c k a -> a
(a -> m) -> FlattenedMap c k a -> m
(a -> m) -> FlattenedMap c k a -> m
(a -> b -> b) -> b -> FlattenedMap c k a -> b
(a -> b -> b) -> b -> FlattenedMap c k a -> b
(b -> a -> b) -> b -> FlattenedMap c k a -> b
(b -> a -> b) -> b -> FlattenedMap c k a -> b
(a -> a -> a) -> FlattenedMap c k a -> a
(a -> a -> a) -> FlattenedMap c k a -> a
(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
product :: FlattenedMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
sum :: FlattenedMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
FlattenedMap c k a -> a
minimum :: FlattenedMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
maximum :: FlattenedMap c k a -> a
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
FlattenedMap c k a -> a
elem :: a -> FlattenedMap c k a -> Bool
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> FlattenedMap c k a -> Bool
length :: FlattenedMap c k a -> Int
$clength :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Int
null :: FlattenedMap c k a -> Bool
$cnull :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> Bool
toList :: FlattenedMap c k a -> [a]
$ctoList :: forall (c :: * -> * -> *) k a.
Foldable (c k) =>
FlattenedMap c k a -> [a]
foldl1 :: (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 :: (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' :: (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 :: (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' :: (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 :: (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' :: (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 :: (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 :: FlattenedMap c k m -> m
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
FlattenedMap c k m -> m
Foldable,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)
(a -> f b) -> FlattenedMap c k a -> f (FlattenedMap c 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 =>
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)
sequence :: 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 :: (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 :: 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 :: (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)
$cp2Traversable :: forall (c :: * -> * -> *) k.
Traversable (c k) =>
Foldable (FlattenedMap c k)
$cp1Traversable :: forall (c :: * -> * -> *) k.
Traversable (c k) =>
Functor (FlattenedMap c k)
Traversable,a -> FlattenedMap c k b -> FlattenedMap c k a
(a -> b) -> FlattenedMap c k a -> FlattenedMap c k b
(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
<$ :: 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 :: (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)

-- | 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 (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 :: (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 (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)
traverse (s, s) -> Parser (k, v)
parsePair Vector (s, s)
pairVec
  where
    vlen :: Int
vlen = Vector s -> 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 (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 (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 :: (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 (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
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.
--
-- >>> Aeson.eitherDecode "{\"ten\": 10}" :: Either String (GMap HashMap Text Int)
-- Right (GMap {gmapFlat = False, gmapValue = fromList [("ten",10)]})
-- >>> Aeson.eitherDecode "[\"ten\", 10]" :: Either String (GMap HashMap Text Int)
-- Right (GMap {gmapFlat = True, gmapValue = fromList [("ten",10)]})
-- >>> Aeson.encode $ GMap False (HashMap.fromList [(9, "nine")] :: HashMap Int Text)
-- "{\"9\":\"nine\"}"
-- >>> Aeson.encode $ GMap True (HashMap.fromList [(9, "nine")] :: HashMap Int Text)
-- "[9,\"nine\"]"
data GMap c k v =
  GMap
  { 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.
    GMap c k v -> c k v
gmapValue :: !(c k v)
    -- ^ Map implementation.
  }
  deriving (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
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,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
/= :: 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,GMap c k a -> Bool
(a -> m) -> GMap c k a -> m
(a -> b -> b) -> b -> GMap c k a -> b
(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
product :: GMap c k a -> a
$cproduct :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
sum :: GMap c k a -> a
$csum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Num a) =>
GMap c k a -> a
minimum :: GMap c k a -> a
$cminimum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
maximum :: GMap c k a -> a
$cmaximum :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Ord a) =>
GMap c k a -> a
elem :: a -> GMap c k a -> Bool
$celem :: forall (c :: * -> * -> *) k a.
(Foldable (c k), Eq a) =>
a -> GMap c k a -> Bool
length :: GMap c k a -> Int
$clength :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Int
null :: GMap c k a -> Bool
$cnull :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> Bool
toList :: GMap c k a -> [a]
$ctoList :: forall (c :: * -> * -> *) k a. Foldable (c k) => GMap c k a -> [a]
foldl1 :: (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 :: (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' :: (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 :: (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' :: (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 :: (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' :: (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 :: (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 :: GMap c k m -> m
$cfold :: forall (c :: * -> * -> *) k m.
(Foldable (c k), Monoid m) =>
GMap c k m -> m
Foldable,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)
(a -> f b) -> GMap c k a -> f (GMap c 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 => 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)
sequence :: 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 :: (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 :: 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 :: (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)
$cp2Traversable :: forall (c :: * -> * -> *) k.
Traversable (c k) =>
Foldable (GMap c k)
$cp1Traversable :: forall (c :: * -> * -> *) k.
Traversable (c k) =>
Functor (GMap c k)
Traversable,a -> GMap c k b -> GMap c k a
(a -> b) -> GMap c k a -> GMap c k b
(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
<$ :: 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 :: (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)

-- | 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 :: (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 (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 (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 (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 :: 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'.
--
-- >>> Aeson.eitherDecode "{\"1\": \"one\"}" :: Either String (GMapEntry Int Text)
-- Right (GMapEntry {gmapEntryFlat = False, gmapEntryKey = 1, gmapEntryValue = "one"})
-- >>> Aeson.eitherDecode "[1, \"one\"]" :: Either String (GMapEntry Int Text)
-- Right (GMapEntry {gmapEntryFlat = True, gmapEntryKey = 1, gmapEntryValue = "one"})
-- >>> Aeson.encode (GMapEntry False "one" 1 :: GMapEntry Text Int)
-- "{\"one\":1}"
-- >>> Aeson.encode (GMapEntry True "one" 1 :: GMapEntry Text Int)
-- "[\"one\",1]"
--
-- 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.
--
-- >>> Aeson.eitherDecode "{\"key\":1, \"value\": \"one\"}" :: Either String (GMapEntry Int Text)
-- Right (GMapEntry {gmapEntryFlat = False, gmapEntryKey = 1, gmapEntryValue = "one"})
data GMapEntry k v =
  GMapEntry
  { GMapEntry k v -> Bool
gmapEntryFlat :: !Bool,
    GMapEntry k v -> k
gmapEntryKey :: !k,
    GMapEntry k v -> v
gmapEntryValue :: !v
  }
  deriving (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
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,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
/= :: 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,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
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
$cp1Ord :: forall k v. (Ord k, Ord v) => Eq (GMapEntry k v)
Ord,GMapEntry k a -> Bool
(a -> m) -> GMapEntry k a -> m
(a -> b -> b) -> b -> GMapEntry k a -> b
(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 a. GMapEntry k a -> 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
product :: GMapEntry k a -> a
$cproduct :: forall k a. Num a => GMapEntry k a -> a
sum :: GMapEntry k a -> a
$csum :: forall k a. Num a => GMapEntry k a -> a
minimum :: GMapEntry k a -> a
$cminimum :: forall k a. Ord a => GMapEntry k a -> a
maximum :: GMapEntry k a -> a
$cmaximum :: forall k a. Ord a => GMapEntry k a -> a
elem :: a -> GMapEntry k a -> Bool
$celem :: forall k a. Eq a => a -> GMapEntry k a -> Bool
length :: GMapEntry k a -> Int
$clength :: forall k a. GMapEntry k a -> Int
null :: GMapEntry k a -> Bool
$cnull :: forall k a. GMapEntry k a -> Bool
toList :: GMapEntry k a -> [a]
$ctoList :: forall k a. GMapEntry k a -> [a]
foldl1 :: (a -> a -> a) -> GMapEntry k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldr1 :: (a -> a -> a) -> GMapEntry k a -> a
$cfoldr1 :: forall k a. (a -> a -> a) -> GMapEntry k a -> a
foldl' :: (b -> a -> b) -> b -> GMapEntry k a -> b
$cfoldl' :: forall k b a. (b -> a -> b) -> b -> GMapEntry k a -> b
foldl :: (b -> a -> b) -> b -> GMapEntry k a -> b
$cfoldl :: forall k b a. (b -> a -> b) -> b -> GMapEntry k a -> b
foldr' :: (a -> b -> b) -> b -> GMapEntry k a -> b
$cfoldr' :: forall k a b. (a -> b -> b) -> b -> GMapEntry k a -> b
foldr :: (a -> b -> b) -> b -> GMapEntry k a -> b
$cfoldr :: forall k a b. (a -> b -> b) -> b -> GMapEntry k a -> b
foldMap' :: (a -> m) -> GMapEntry k a -> m
$cfoldMap' :: forall k m a. Monoid m => (a -> m) -> GMapEntry k a -> m
foldMap :: (a -> m) -> GMapEntry k a -> m
$cfoldMap :: forall k m a. Monoid m => (a -> m) -> GMapEntry k a -> m
fold :: GMapEntry k m -> m
$cfold :: forall k m. Monoid m => GMapEntry k m -> m
Foldable,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)
(a -> f b) -> GMapEntry k a -> f (GMapEntry k b)
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)
sequence :: GMapEntry k (m a) -> m (GMapEntry k a)
$csequence :: forall k (m :: * -> *) a.
Monad m =>
GMapEntry k (m a) -> m (GMapEntry k a)
mapM :: (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 :: GMapEntry k (f a) -> f (GMapEntry k a)
$csequenceA :: forall k (f :: * -> *) a.
Applicative f =>
GMapEntry k (f a) -> f (GMapEntry k a)
traverse :: (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)
$cp2Traversable :: forall k. Foldable (GMapEntry k)
$cp1Traversable :: forall k. Functor (GMapEntry k)
Traversable,a -> GMapEntry k b -> GMapEntry k a
(a -> b) -> GMapEntry k a -> GMapEntry k b
(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
<$ :: a -> GMapEntry k b -> GMapEntry k a
$c<$ :: forall k a b. a -> GMapEntry k b -> GMapEntry k a
fmap :: (a -> b) -> GMapEntry k a -> GMapEntry k b
$cfmap :: forall k a b. (a -> b) -> GMapEntry k a -> GMapEntry k b
Functor)

parseKeyValueToEntry :: (s -> Parser k)
                     -> (s -> Parser v)
                     -> KeyMap s
                     -> Parser (Maybe (GMapEntry k v))
parseKeyValueToEntry :: (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 (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 (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 (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 (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 :: (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 (m :: * -> *) a. Monad m => a -> m a
return Maybe v
forall a. Maybe a
Nothing) ((v -> Maybe v) -> Parser v -> Parser (Maybe v)
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 :: (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 (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 (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 (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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Parser k
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 (m :: * -> *) a. Monad m => a -> m a
return Text -> Parser k
p
      FromJSONKeyValue Value -> Parser k
_ -> String -> Parser (Text -> Parser k)
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 (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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap k -> Parser k
forall (m :: * -> *) a. Monad m => a -> m a
return Text -> k
coerce

orElseM :: Monad m => m (Maybe a) -> m (Maybe a) -> m (Maybe a)
orElseM :: 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 (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 :: (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 (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 (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 (m :: * -> *) a. Monad m => a -> m a
return GMapEntry k v
ret
   Maybe (GMapEntry k v)
Nothing -> String -> Parser (GMapEntry k v)
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 (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' :: 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 :: 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 :: GMapEntry k v -> GMap c k v
singleton GMapEntry k v
e = GMap :: forall (c :: * -> * -> *) k v. Bool -> c k v -> GMap c k v
GMap { gmapFlat :: Bool
gmapFlat = GMapEntry k v -> Bool
forall k a. GMapEntry k a -> 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 :: 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