{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE NoMonomorphismRestriction  #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE UndecidableInstances       #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Aws.DynamoDb.Core
-- Copyright   :  Soostone Inc, Chris Allen
-- License     :  BSD3
--
-- Maintainer  :  Ozgun Ataman <ozgun.ataman@soostone.com>
-- Stability   :  experimental
--
-- Shared types and utilities for DyanmoDb functionality.
----------------------------------------------------------------------------

module Aws.DynamoDb.Core
    (
    -- * Configuration and Regions
      Region (..)
    , ddbLocal
    , ddbUsEast1
    , ddbUsWest1
    , ddbUsWest2
    , ddbEuWest1
    , ddbEuWest2
    , ddbEuCentral1
    , ddbApNe1
    , ddbApSe1
    , ddbApSe2
    , ddbSaEast1
    , DdbConfiguration (..)

    -- * DynamoDB values
    , DValue (..)

    -- * Converting to/from 'DValue'
    , DynVal(..)
    , toValue, fromValue
    , Bin (..)
    , OldBool(..)

    -- * Defining new 'DynVal' instances
    , DynData(..)
    , DynBinary(..), DynNumber(..), DynString(..), DynBool(..)

    -- * Working with key/value pairs
    , Attribute (..)
    , parseAttributeJson
    , attributeJson
    , attributesJson

    , attrTuple
    , attr
    , attrAs
    , text, int, double
    , PrimaryKey (..)
    , hk
    , hrk

    -- * Working with objects (attribute collections)
    , Item
    , item
    , attributes
    , ToDynItem (..)
    , FromDynItem (..)
    , fromItem
    , Parser (..)
    , getAttr
    , getAttr'
    , parseAttr

    -- * Common types used by operations
    , Conditions (..)
    , conditionsJson
    , expectsJson

    , Condition (..)
    , conditionJson
    , CondOp (..)
    , CondMerge (..)
    , ConsumedCapacity (..)
    , ReturnConsumption (..)
    , ItemCollectionMetrics (..)
    , ReturnItemCollectionMetrics (..)
    , UpdateReturn (..)
    , QuerySelect (..)
    , querySelectJson

    -- * Size estimation
    , DynSize (..)
    , nullAttr

    -- * Responses & Errors
    , DdbResponse (..)
    , DdbErrCode (..)
    , shouldRetry
    , DdbError (..)

    -- * Internal Helpers
    , ddbSignQuery
    , AmazonError (..)
    , ddbResponseConsumer
    , ddbHttp
    , ddbHttps

    ) where


-------------------------------------------------------------------------------
import           Control.Applicative
import qualified Control.Exception            as C
import           Control.Monad
#if MIN_VERSION_base(4,9,0)
import qualified Control.Monad.Fail           as Fail
#endif
import           Control.Monad.Trans
import           Control.Monad.Trans.Resource (throwM)
import qualified Crypto.Hash                  as CH
import           Data.Aeson
import qualified Data.Aeson                   as A
import qualified Data.Aeson.Key               as AK
import qualified Data.Aeson.KeyMap            as KM
import           Data.Aeson.Parser            as A (json')
import           Data.Aeson.Types             (Pair, parseEither)
import qualified Data.Aeson.Types             as A
import qualified Data.Attoparsec.ByteString   as AttoB (endOfInput)
import qualified Data.Attoparsec.Text         as Atto
import qualified Data.ByteArray               as ByteArray
import qualified Data.ByteString.Base16       as Base16
import qualified Data.ByteString.Base64       as Base64
import qualified Data.ByteString.Char8        as B
import qualified Data.CaseInsensitive         as CI
import           Data.Conduit
import           Data.Conduit.Attoparsec      (sinkParser)
import           Data.Default
import           Data.Function                (on)
import           Data.Int
import           Data.IORef
import           Data.List
import qualified Data.Map                     as M
import           Data.Maybe
import           Data.Monoid                  ()
import qualified Data.Semigroup               as Sem
import           Data.Proxy
import           Data.Scientific
import qualified Data.Serialize               as Ser
import qualified Data.Set                     as S
import           Data.String
import           Data.Tagged
import qualified Data.Text                    as T
import qualified Data.Text.Encoding           as T
import           Data.Time
import           Data.Typeable
import qualified Data.Vector                  as V
import           Data.Word
import qualified Network.HTTP.Conduit         as HTTP
import qualified Network.HTTP.Types           as HTTP
import           Safe
-------------------------------------------------------------------------------
import           Aws.Core
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- | Boolean values stored in DynamoDb. Only used in defining new
-- 'DynVal' instances.
newtype DynBool = DynBool { DynBool -> Bool
unDynBool :: Bool }
    deriving (DynBool -> DynBool -> Bool
(DynBool -> DynBool -> Bool)
-> (DynBool -> DynBool -> Bool) -> Eq DynBool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DynBool -> DynBool -> Bool
== :: DynBool -> DynBool -> Bool
$c/= :: DynBool -> DynBool -> Bool
/= :: DynBool -> DynBool -> Bool
Eq,Int -> DynBool -> ShowS
[DynBool] -> ShowS
DynBool -> String
(Int -> DynBool -> ShowS)
-> (DynBool -> String) -> ([DynBool] -> ShowS) -> Show DynBool
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DynBool -> ShowS
showsPrec :: Int -> DynBool -> ShowS
$cshow :: DynBool -> String
show :: DynBool -> String
$cshowList :: [DynBool] -> ShowS
showList :: [DynBool] -> ShowS
Show,ReadPrec [DynBool]
ReadPrec DynBool
Int -> ReadS DynBool
ReadS [DynBool]
(Int -> ReadS DynBool)
-> ReadS [DynBool]
-> ReadPrec DynBool
-> ReadPrec [DynBool]
-> Read DynBool
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DynBool
readsPrec :: Int -> ReadS DynBool
$creadList :: ReadS [DynBool]
readList :: ReadS [DynBool]
$creadPrec :: ReadPrec DynBool
readPrec :: ReadPrec DynBool
$creadListPrec :: ReadPrec [DynBool]
readListPrec :: ReadPrec [DynBool]
Read,Eq DynBool
Eq DynBool =>
(DynBool -> DynBool -> Ordering)
-> (DynBool -> DynBool -> Bool)
-> (DynBool -> DynBool -> Bool)
-> (DynBool -> DynBool -> Bool)
-> (DynBool -> DynBool -> Bool)
-> (DynBool -> DynBool -> DynBool)
-> (DynBool -> DynBool -> DynBool)
-> Ord DynBool
DynBool -> DynBool -> Bool
DynBool -> DynBool -> Ordering
DynBool -> DynBool -> DynBool
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
$ccompare :: DynBool -> DynBool -> Ordering
compare :: DynBool -> DynBool -> Ordering
$c< :: DynBool -> DynBool -> Bool
< :: DynBool -> DynBool -> Bool
$c<= :: DynBool -> DynBool -> Bool
<= :: DynBool -> DynBool -> Bool
$c> :: DynBool -> DynBool -> Bool
> :: DynBool -> DynBool -> Bool
$c>= :: DynBool -> DynBool -> Bool
>= :: DynBool -> DynBool -> Bool
$cmax :: DynBool -> DynBool -> DynBool
max :: DynBool -> DynBool -> DynBool
$cmin :: DynBool -> DynBool -> DynBool
min :: DynBool -> DynBool -> DynBool
Ord,Typeable)


-------------------------------------------------------------------------------
-- | Numeric values stored in DynamoDb. Only used in defining new
-- 'DynVal' instances.
newtype DynNumber = DynNumber { DynNumber -> Scientific
unDynNumber :: Scientific }
    deriving (DynNumber -> DynNumber -> Bool
(DynNumber -> DynNumber -> Bool)
-> (DynNumber -> DynNumber -> Bool) -> Eq DynNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DynNumber -> DynNumber -> Bool
== :: DynNumber -> DynNumber -> Bool
$c/= :: DynNumber -> DynNumber -> Bool
/= :: DynNumber -> DynNumber -> Bool
Eq,Int -> DynNumber -> ShowS
[DynNumber] -> ShowS
DynNumber -> String
(Int -> DynNumber -> ShowS)
-> (DynNumber -> String)
-> ([DynNumber] -> ShowS)
-> Show DynNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DynNumber -> ShowS
showsPrec :: Int -> DynNumber -> ShowS
$cshow :: DynNumber -> String
show :: DynNumber -> String
$cshowList :: [DynNumber] -> ShowS
showList :: [DynNumber] -> ShowS
Show,ReadPrec [DynNumber]
ReadPrec DynNumber
Int -> ReadS DynNumber
ReadS [DynNumber]
(Int -> ReadS DynNumber)
-> ReadS [DynNumber]
-> ReadPrec DynNumber
-> ReadPrec [DynNumber]
-> Read DynNumber
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DynNumber
readsPrec :: Int -> ReadS DynNumber
$creadList :: ReadS [DynNumber]
readList :: ReadS [DynNumber]
$creadPrec :: ReadPrec DynNumber
readPrec :: ReadPrec DynNumber
$creadListPrec :: ReadPrec [DynNumber]
readListPrec :: ReadPrec [DynNumber]
Read,Eq DynNumber
Eq DynNumber =>
(DynNumber -> DynNumber -> Ordering)
-> (DynNumber -> DynNumber -> Bool)
-> (DynNumber -> DynNumber -> Bool)
-> (DynNumber -> DynNumber -> Bool)
-> (DynNumber -> DynNumber -> Bool)
-> (DynNumber -> DynNumber -> DynNumber)
-> (DynNumber -> DynNumber -> DynNumber)
-> Ord DynNumber
DynNumber -> DynNumber -> Bool
DynNumber -> DynNumber -> Ordering
DynNumber -> DynNumber -> DynNumber
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
$ccompare :: DynNumber -> DynNumber -> Ordering
compare :: DynNumber -> DynNumber -> Ordering
$c< :: DynNumber -> DynNumber -> Bool
< :: DynNumber -> DynNumber -> Bool
$c<= :: DynNumber -> DynNumber -> Bool
<= :: DynNumber -> DynNumber -> Bool
$c> :: DynNumber -> DynNumber -> Bool
> :: DynNumber -> DynNumber -> Bool
$c>= :: DynNumber -> DynNumber -> Bool
>= :: DynNumber -> DynNumber -> Bool
$cmax :: DynNumber -> DynNumber -> DynNumber
max :: DynNumber -> DynNumber -> DynNumber
$cmin :: DynNumber -> DynNumber -> DynNumber
min :: DynNumber -> DynNumber -> DynNumber
Ord,Typeable)


-------------------------------------------------------------------------------
-- | String values stored in DynamoDb. Only used in defining new
-- 'DynVal' instances.
newtype DynString = DynString { DynString -> Text
unDynString :: T.Text }
    deriving (DynString -> DynString -> Bool
(DynString -> DynString -> Bool)
-> (DynString -> DynString -> Bool) -> Eq DynString
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DynString -> DynString -> Bool
== :: DynString -> DynString -> Bool
$c/= :: DynString -> DynString -> Bool
/= :: DynString -> DynString -> Bool
Eq,Int -> DynString -> ShowS
[DynString] -> ShowS
DynString -> String
(Int -> DynString -> ShowS)
-> (DynString -> String)
-> ([DynString] -> ShowS)
-> Show DynString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DynString -> ShowS
showsPrec :: Int -> DynString -> ShowS
$cshow :: DynString -> String
show :: DynString -> String
$cshowList :: [DynString] -> ShowS
showList :: [DynString] -> ShowS
Show,ReadPrec [DynString]
ReadPrec DynString
Int -> ReadS DynString
ReadS [DynString]
(Int -> ReadS DynString)
-> ReadS [DynString]
-> ReadPrec DynString
-> ReadPrec [DynString]
-> Read DynString
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DynString
readsPrec :: Int -> ReadS DynString
$creadList :: ReadS [DynString]
readList :: ReadS [DynString]
$creadPrec :: ReadPrec DynString
readPrec :: ReadPrec DynString
$creadListPrec :: ReadPrec [DynString]
readListPrec :: ReadPrec [DynString]
Read,Eq DynString
Eq DynString =>
(DynString -> DynString -> Ordering)
-> (DynString -> DynString -> Bool)
-> (DynString -> DynString -> Bool)
-> (DynString -> DynString -> Bool)
-> (DynString -> DynString -> Bool)
-> (DynString -> DynString -> DynString)
-> (DynString -> DynString -> DynString)
-> Ord DynString
DynString -> DynString -> Bool
DynString -> DynString -> Ordering
DynString -> DynString -> DynString
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
$ccompare :: DynString -> DynString -> Ordering
compare :: DynString -> DynString -> Ordering
$c< :: DynString -> DynString -> Bool
< :: DynString -> DynString -> Bool
$c<= :: DynString -> DynString -> Bool
<= :: DynString -> DynString -> Bool
$c> :: DynString -> DynString -> Bool
> :: DynString -> DynString -> Bool
$c>= :: DynString -> DynString -> Bool
>= :: DynString -> DynString -> Bool
$cmax :: DynString -> DynString -> DynString
max :: DynString -> DynString -> DynString
$cmin :: DynString -> DynString -> DynString
min :: DynString -> DynString -> DynString
Ord,Typeable)


-------------------------------------------------------------------------------
-- | Binary values stored in DynamoDb. Only used in defining new
-- 'DynVal' instances.
newtype DynBinary = DynBinary { DynBinary -> ByteString
unDynBinary :: B.ByteString }
    deriving (DynBinary -> DynBinary -> Bool
(DynBinary -> DynBinary -> Bool)
-> (DynBinary -> DynBinary -> Bool) -> Eq DynBinary
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DynBinary -> DynBinary -> Bool
== :: DynBinary -> DynBinary -> Bool
$c/= :: DynBinary -> DynBinary -> Bool
/= :: DynBinary -> DynBinary -> Bool
Eq,Int -> DynBinary -> ShowS
[DynBinary] -> ShowS
DynBinary -> String
(Int -> DynBinary -> ShowS)
-> (DynBinary -> String)
-> ([DynBinary] -> ShowS)
-> Show DynBinary
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DynBinary -> ShowS
showsPrec :: Int -> DynBinary -> ShowS
$cshow :: DynBinary -> String
show :: DynBinary -> String
$cshowList :: [DynBinary] -> ShowS
showList :: [DynBinary] -> ShowS
Show,ReadPrec [DynBinary]
ReadPrec DynBinary
Int -> ReadS DynBinary
ReadS [DynBinary]
(Int -> ReadS DynBinary)
-> ReadS [DynBinary]
-> ReadPrec DynBinary
-> ReadPrec [DynBinary]
-> Read DynBinary
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DynBinary
readsPrec :: Int -> ReadS DynBinary
$creadList :: ReadS [DynBinary]
readList :: ReadS [DynBinary]
$creadPrec :: ReadPrec DynBinary
readPrec :: ReadPrec DynBinary
$creadListPrec :: ReadPrec [DynBinary]
readListPrec :: ReadPrec [DynBinary]
Read,Eq DynBinary
Eq DynBinary =>
(DynBinary -> DynBinary -> Ordering)
-> (DynBinary -> DynBinary -> Bool)
-> (DynBinary -> DynBinary -> Bool)
-> (DynBinary -> DynBinary -> Bool)
-> (DynBinary -> DynBinary -> Bool)
-> (DynBinary -> DynBinary -> DynBinary)
-> (DynBinary -> DynBinary -> DynBinary)
-> Ord DynBinary
DynBinary -> DynBinary -> Bool
DynBinary -> DynBinary -> Ordering
DynBinary -> DynBinary -> DynBinary
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
$ccompare :: DynBinary -> DynBinary -> Ordering
compare :: DynBinary -> DynBinary -> Ordering
$c< :: DynBinary -> DynBinary -> Bool
< :: DynBinary -> DynBinary -> Bool
$c<= :: DynBinary -> DynBinary -> Bool
<= :: DynBinary -> DynBinary -> Bool
$c> :: DynBinary -> DynBinary -> Bool
> :: DynBinary -> DynBinary -> Bool
$c>= :: DynBinary -> DynBinary -> Bool
>= :: DynBinary -> DynBinary -> Bool
$cmax :: DynBinary -> DynBinary -> DynBinary
max :: DynBinary -> DynBinary -> DynBinary
$cmin :: DynBinary -> DynBinary -> DynBinary
min :: DynBinary -> DynBinary -> DynBinary
Ord,Typeable)


-------------------------------------------------------------------------------
-- | An internally used closed typeclass for values that have direct
-- DynamoDb representations. Based on AWS API, this is basically
-- numbers, strings and binary blobs.
--
-- This is here so that any 'DynVal' haskell value can automatically
-- be lifted to a list or a 'Set' without any instance code
-- duplication.
--
-- Do not try to create your own instances.
class Ord a => DynData a where
    fromData :: a -> DValue
    toData :: DValue -> Maybe a

instance DynData DynBool where
    fromData :: DynBool -> DValue
fromData (DynBool Bool
i) = Bool -> DValue
DBool Bool
i
    toData :: DValue -> Maybe DynBool
toData (DBool Bool
i) = DynBool -> Maybe DynBool
forall a. a -> Maybe a
Just (DynBool -> Maybe DynBool) -> DynBool -> Maybe DynBool
forall a b. (a -> b) -> a -> b
$ Bool -> DynBool
DynBool Bool
i
    toData (DNum Scientific
i) = Bool -> DynBool
DynBool (Bool -> DynBool) -> Maybe Bool -> Maybe DynBool
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` do
        (Int
i' :: Int) <- Scientific -> Maybe Int
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
        case Int
i' of
          Int
0 -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
          Int
1 -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
          Int
_ -> Maybe Bool
forall a. Maybe a
Nothing
    toData DValue
_ = Maybe DynBool
forall a. Maybe a
Nothing

instance DynData (S.Set DynBool) where
    fromData :: Set DynBool -> DValue
fromData Set DynBool
set = Set Bool -> DValue
DBoolSet ((DynBool -> Bool) -> Set DynBool -> Set Bool
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map DynBool -> Bool
unDynBool Set DynBool
set)
    toData :: DValue -> Maybe (Set DynBool)
toData (DBoolSet Set Bool
i) = Set DynBool -> Maybe (Set DynBool)
forall a. a -> Maybe a
Just (Set DynBool -> Maybe (Set DynBool))
-> Set DynBool -> Maybe (Set DynBool)
forall a b. (a -> b) -> a -> b
$ (Bool -> DynBool) -> Set Bool -> Set DynBool
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map Bool -> DynBool
DynBool Set Bool
i
    toData DValue
_ = Maybe (Set DynBool)
forall a. Maybe a
Nothing

instance DynData DynNumber where
    fromData :: DynNumber -> DValue
fromData (DynNumber Scientific
i) = Scientific -> DValue
DNum Scientific
i
    toData :: DValue -> Maybe DynNumber
toData (DNum Scientific
i) = DynNumber -> Maybe DynNumber
forall a. a -> Maybe a
Just (DynNumber -> Maybe DynNumber) -> DynNumber -> Maybe DynNumber
forall a b. (a -> b) -> a -> b
$ Scientific -> DynNumber
DynNumber Scientific
i
    toData DValue
_ = Maybe DynNumber
forall a. Maybe a
Nothing

instance DynData (S.Set DynNumber) where
    fromData :: Set DynNumber -> DValue
fromData Set DynNumber
set = Set Scientific -> DValue
DNumSet ((DynNumber -> Scientific) -> Set DynNumber -> Set Scientific
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map DynNumber -> Scientific
unDynNumber Set DynNumber
set)
    toData :: DValue -> Maybe (Set DynNumber)
toData (DNumSet Set Scientific
i) = Set DynNumber -> Maybe (Set DynNumber)
forall a. a -> Maybe a
Just (Set DynNumber -> Maybe (Set DynNumber))
-> Set DynNumber -> Maybe (Set DynNumber)
forall a b. (a -> b) -> a -> b
$ (Scientific -> DynNumber) -> Set Scientific -> Set DynNumber
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map Scientific -> DynNumber
DynNumber Set Scientific
i
    toData DValue
_ = Maybe (Set DynNumber)
forall a. Maybe a
Nothing

instance DynData DynString where
    fromData :: DynString -> DValue
fromData (DynString Text
i) = Text -> DValue
DString Text
i
    toData :: DValue -> Maybe DynString
toData (DString Text
i) = DynString -> Maybe DynString
forall a. a -> Maybe a
Just (DynString -> Maybe DynString) -> DynString -> Maybe DynString
forall a b. (a -> b) -> a -> b
$ Text -> DynString
DynString Text
i
    toData DValue
_ = Maybe DynString
forall a. Maybe a
Nothing

instance DynData (S.Set DynString) where
    fromData :: Set DynString -> DValue
fromData Set DynString
set = Set Text -> DValue
DStringSet ((DynString -> Text) -> Set DynString -> Set Text
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map DynString -> Text
unDynString Set DynString
set)
    toData :: DValue -> Maybe (Set DynString)
toData (DStringSet Set Text
i) = Set DynString -> Maybe (Set DynString)
forall a. a -> Maybe a
Just (Set DynString -> Maybe (Set DynString))
-> Set DynString -> Maybe (Set DynString)
forall a b. (a -> b) -> a -> b
$ (Text -> DynString) -> Set Text -> Set DynString
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map Text -> DynString
DynString Set Text
i
    toData DValue
_ = Maybe (Set DynString)
forall a. Maybe a
Nothing

instance DynData DynBinary where
    fromData :: DynBinary -> DValue
fromData (DynBinary ByteString
i) = ByteString -> DValue
DBinary ByteString
i
    toData :: DValue -> Maybe DynBinary
toData (DBinary ByteString
i) = DynBinary -> Maybe DynBinary
forall a. a -> Maybe a
Just (DynBinary -> Maybe DynBinary) -> DynBinary -> Maybe DynBinary
forall a b. (a -> b) -> a -> b
$ ByteString -> DynBinary
DynBinary ByteString
i
    toData DValue
_ = Maybe DynBinary
forall a. Maybe a
Nothing

instance DynData (S.Set DynBinary) where
    fromData :: Set DynBinary -> DValue
fromData Set DynBinary
set = Set ByteString -> DValue
DBinSet ((DynBinary -> ByteString) -> Set DynBinary -> Set ByteString
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map DynBinary -> ByteString
unDynBinary Set DynBinary
set)
    toData :: DValue -> Maybe (Set DynBinary)
toData (DBinSet Set ByteString
i) = Set DynBinary -> Maybe (Set DynBinary)
forall a. a -> Maybe a
Just (Set DynBinary -> Maybe (Set DynBinary))
-> Set DynBinary -> Maybe (Set DynBinary)
forall a b. (a -> b) -> a -> b
$ (ByteString -> DynBinary) -> Set ByteString -> Set DynBinary
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map ByteString -> DynBinary
DynBinary Set ByteString
i
    toData DValue
_ = Maybe (Set DynBinary)
forall a. Maybe a
Nothing

instance DynData DValue where
    fromData :: DValue -> DValue
fromData = DValue -> DValue
forall a. a -> a
id
    toData :: DValue -> Maybe DValue
toData = DValue -> Maybe DValue
forall a. a -> Maybe a
Just


-------------------------------------------------------------------------------
-- | Class of Haskell types that can be represented as DynamoDb values.
--
-- This is the conversion layer; instantiate this class for your own
-- types and then use the 'toValue' and 'fromValue' combinators to
-- convert in application code.
--
-- Each Haskell type instantiated with this class will map to a
-- DynamoDb-supported type that most naturally represents it.
class DynData (DynRep a) => DynVal a where

    -- | Which of the 'DynData' instances does this data type directly
    -- map to?
    type DynRep a

    -- | Convert to representation
    toRep :: a -> DynRep a

    -- | Convert from representation
    fromRep :: DynRep a -> Maybe a


-------------------------------------------------------------------------------
-- | Any singular 'DynVal' can be upgraded to a list.
instance (DynData (DynRep [a]), DynVal a) => DynVal [a] where
    type DynRep [a] = S.Set (DynRep a)
    fromRep :: DynRep [a] -> Maybe [a]
fromRep DynRep [a]
set = (DynRep a -> Maybe a) -> [DynRep a] -> Maybe [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM DynRep a -> Maybe a
forall a. DynVal a => DynRep a -> Maybe a
fromRep ([DynRep a] -> Maybe [a]) -> [DynRep a] -> Maybe [a]
forall a b. (a -> b) -> a -> b
$ Set (DynRep a) -> [DynRep a]
forall a. Set a -> [a]
S.toList Set (DynRep a)
DynRep [a]
set
    toRep :: [a] -> DynRep [a]
toRep [a]
as = [DynRep a] -> Set (DynRep a)
forall a. Ord a => [a] -> Set a
S.fromList ([DynRep a] -> Set (DynRep a)) -> [DynRep a] -> Set (DynRep a)
forall a b. (a -> b) -> a -> b
$ (a -> DynRep a) -> [a] -> [DynRep a]
forall a b. (a -> b) -> [a] -> [b]
map a -> DynRep a
forall a. DynVal a => a -> DynRep a
toRep [a]
as


-------------------------------------------------------------------------------
-- | Any singular 'DynVal' can be upgraded to a 'Set'.
instance (DynData (DynRep (S.Set a)), DynVal a, Ord a) => DynVal (S.Set a) where
    type DynRep (S.Set a) = S.Set (DynRep a)
    fromRep :: DynRep (Set a) -> Maybe (Set a)
fromRep DynRep (Set a)
set = ([a] -> Set a) -> Maybe [a] -> Maybe (Set a)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> Set a
forall a. Ord a => [a] -> Set a
S.fromList (Maybe [a] -> Maybe (Set a))
-> ([DynRep a] -> Maybe [a]) -> [DynRep a] -> Maybe (Set a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DynRep a -> Maybe a) -> [DynRep a] -> Maybe [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM DynRep a -> Maybe a
forall a. DynVal a => DynRep a -> Maybe a
fromRep ([DynRep a] -> Maybe (Set a)) -> [DynRep a] -> Maybe (Set a)
forall a b. (a -> b) -> a -> b
$ Set (DynRep a) -> [DynRep a]
forall a. Set a -> [a]
S.toList Set (DynRep a)
DynRep (Set a)
set
    toRep :: Set a -> DynRep (Set a)
toRep Set a
as = (a -> DynRep a) -> Set a -> Set (DynRep a)
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map a -> DynRep a
forall a. DynVal a => a -> DynRep a
toRep Set a
as


instance DynVal DValue where
    type DynRep DValue = DValue
    fromRep :: DynRep DValue -> Maybe DValue
fromRep = DValue -> Maybe DValue
DynRep DValue -> Maybe DValue
forall a. a -> Maybe a
Just
    toRep :: DValue -> DynRep DValue
toRep   = DValue -> DValue
DValue -> DynRep DValue
forall a. a -> a
id

instance DynVal Bool where
    type DynRep Bool = DynBool
    fromRep :: DynRep Bool -> Maybe Bool
fromRep (DynBool Bool
i) = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
i
    toRep :: Bool -> DynRep Bool
toRep Bool
i = Bool -> DynBool
DynBool Bool
i

instance DynVal Int where
    type DynRep Int = DynNumber
    fromRep :: DynRep Int -> Maybe Int
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Int
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Int -> DynRep Int
toRep Int
i = Scientific -> DynNumber
DynNumber (Int -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)


instance DynVal Int8 where
    type DynRep Int8 = DynNumber
    fromRep :: DynRep Int8 -> Maybe Int8
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Int8
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Int8 -> DynRep Int8
toRep Int8
i = Scientific -> DynNumber
DynNumber (Int8 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int8
i)


instance DynVal Int16 where
    type DynRep Int16 = DynNumber
    fromRep :: DynRep Int16 -> Maybe Int16
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Int16
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Int16 -> DynRep Int16
toRep Int16
i = Scientific -> DynNumber
DynNumber (Int16 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int16
i)


instance DynVal Int32 where
    type DynRep Int32 = DynNumber
    fromRep :: DynRep Int32 -> Maybe Int32
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Int32
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Int32 -> DynRep Int32
toRep Int32
i = Scientific -> DynNumber
DynNumber (Int32 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
i)


instance DynVal Int64 where
    type DynRep Int64 = DynNumber
    fromRep :: DynRep Int64 -> Maybe Int64
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Int64
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Int64 -> DynRep Int64
toRep Int64
i = Scientific -> DynNumber
DynNumber (Int64 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i)


instance DynVal Word8 where
    type DynRep Word8 = DynNumber
    fromRep :: DynRep Word8 -> Maybe Word8
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Word8
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Word8 -> DynRep Word8
toRep Word8
i = Scientific -> DynNumber
DynNumber (Word8 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
i)


instance DynVal Word16 where
    type DynRep Word16 = DynNumber
    fromRep :: DynRep Word16 -> Maybe Word16
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Word16
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Word16 -> DynRep Word16
toRep Word16
i = Scientific -> DynNumber
DynNumber (Word16 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
i)


instance DynVal Word32 where
    type DynRep Word32 = DynNumber
    fromRep :: DynRep Word32 -> Maybe Word32
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Word32
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Word32 -> DynRep Word32
toRep Word32
i = Scientific -> DynNumber
DynNumber (Word32 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
i)


instance DynVal Word64 where
    type DynRep Word64 = DynNumber
    fromRep :: DynRep Word64 -> Maybe Word64
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Word64
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Word64 -> DynRep Word64
toRep Word64
i = Scientific -> DynNumber
DynNumber (Word64 -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
i)


instance DynVal Integer where
    type DynRep Integer = DynNumber
    fromRep :: DynRep Integer -> Maybe Integer
fromRep (DynNumber Scientific
i) = Scientific -> Maybe Integer
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
    toRep :: Integer -> DynRep Integer
toRep Integer
i = Scientific -> DynNumber
DynNumber (Integer -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i)


instance DynVal T.Text where
    type DynRep T.Text = DynString
    fromRep :: DynRep Text -> Maybe Text
fromRep (DynString Text
i) = Text -> Maybe Text
forall a. a -> Maybe a
Just Text
i
    toRep :: Text -> DynRep Text
toRep Text
i = Text -> DynString
DynString Text
i


instance DynVal B.ByteString where
    type DynRep B.ByteString = DynBinary
    fromRep :: DynRep ByteString -> Maybe ByteString
fromRep (DynBinary ByteString
i) = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
i
    toRep :: ByteString -> DynRep ByteString
toRep ByteString
i = ByteString -> DynBinary
DynBinary ByteString
i


instance DynVal Double where
    type DynRep Double = DynNumber
    fromRep :: DynRep Double -> Maybe Double
fromRep (DynNumber Scientific
i) = Double -> Maybe Double
forall a. a -> Maybe a
Just (Double -> Maybe Double) -> Double -> Maybe Double
forall a b. (a -> b) -> a -> b
$ Scientific -> Double
forall a. RealFloat a => Scientific -> a
toRealFloat Scientific
i
    toRep :: Double -> DynRep Double
toRep Double
i = Scientific -> DynNumber
DynNumber (Double -> Scientific
forall a. RealFloat a => a -> Scientific
fromFloatDigits Double
i)


-------------------------------------------------------------------------------
-- | Encoded as number of days
instance DynVal Day where
    type DynRep Day = DynNumber
    fromRep :: DynRep Day -> Maybe Day
fromRep (DynNumber Scientific
i) = Integer -> Day
ModifiedJulianDay (Integer -> Day) -> Maybe Integer -> Maybe Day
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Scientific -> Maybe Integer
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i)
    toRep :: Day -> DynRep Day
toRep (ModifiedJulianDay Integer
i) = Scientific -> DynNumber
DynNumber (Integer -> Scientific
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i)


-------------------------------------------------------------------------------
-- | Losslessly encoded via 'Integer' picoseconds
instance DynVal UTCTime where
    type DynRep UTCTime = DynNumber
    fromRep :: DynRep UTCTime -> Maybe UTCTime
fromRep DynRep UTCTime
num = Integer -> UTCTime
fromTS (Integer -> UTCTime) -> Maybe Integer -> Maybe UTCTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynRep Integer -> Maybe Integer
forall a. DynVal a => DynRep a -> Maybe a
fromRep DynRep Integer
DynRep UTCTime
num
    toRep :: UTCTime -> DynRep UTCTime
toRep UTCTime
x = Integer -> DynRep Integer
forall a. DynVal a => a -> DynRep a
toRep (UTCTime -> Integer
toTS UTCTime
x)


-------------------------------------------------------------------------------
pico :: Rational
pico :: Rational
pico = Integer -> Rational
forall a. Real a => a -> Rational
toRational (Integer -> Rational) -> Integer -> Rational
forall a b. (a -> b) -> a -> b
$ (Integer
10 :: Integer) Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
12 :: Integer)


-------------------------------------------------------------------------------
dayPico :: Integer
dayPico :: Integer
dayPico = Integer
86400 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Rational -> Integer
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Rational
pico


-------------------------------------------------------------------------------
-- | Convert UTCTime to picoseconds
--
-- TODO: Optimize performance?
toTS :: UTCTime -> Integer
toTS :: UTCTime -> Integer
toTS (UTCTime (ModifiedJulianDay Integer
i) DiffTime
diff) = Integer
i' Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
diff'
    where
      diff' :: Integer
diff' = Rational -> Integer
forall b. Integral b => Rational -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (DiffTime -> Rational
forall a. Real a => a -> Rational
toRational DiffTime
diff Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
pico)
      i' :: Integer
i' = Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
dayPico


-------------------------------------------------------------------------------
-- | Convert picoseconds to UTCTime
--
-- TODO: Optimize performance?
fromTS :: Integer -> UTCTime
fromTS :: Integer -> UTCTime
fromTS Integer
i = Day -> DiffTime -> UTCTime
UTCTime (Integer -> Day
ModifiedJulianDay Integer
days) DiffTime
diff
    where
      (Integer
days, Integer
secs) = Integer
i Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
dayPico
      diff :: DiffTime
diff = Rational -> DiffTime
forall a. Fractional a => Rational -> a
fromRational ((Integer -> Rational
forall a. Real a => a -> Rational
toRational Integer
secs) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
pico)



-- | Type wrapper for binary data to be written to DynamoDB. Wrap any
-- 'Serialize' instance in there and 'DynVal' will know how to
-- automatically handle conversions in binary form.
newtype Bin a = Bin { forall a. Bin a -> a
getBin :: a }
    deriving (Bin a -> Bin a -> Bool
(Bin a -> Bin a -> Bool) -> (Bin a -> Bin a -> Bool) -> Eq (Bin a)
forall a. Eq a => Bin a -> Bin a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Bin a -> Bin a -> Bool
== :: Bin a -> Bin a -> Bool
$c/= :: forall a. Eq a => Bin a -> Bin a -> Bool
/= :: Bin a -> Bin a -> Bool
Eq,Int -> Bin a -> ShowS
[Bin a] -> ShowS
Bin a -> String
(Int -> Bin a -> ShowS)
-> (Bin a -> String) -> ([Bin a] -> ShowS) -> Show (Bin a)
forall a. Show a => Int -> Bin a -> ShowS
forall a. Show a => [Bin a] -> ShowS
forall a. Show a => Bin a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Bin a -> ShowS
showsPrec :: Int -> Bin a -> ShowS
$cshow :: forall a. Show a => Bin a -> String
show :: Bin a -> String
$cshowList :: forall a. Show a => [Bin a] -> ShowS
showList :: [Bin a] -> ShowS
Show,ReadPrec [Bin a]
ReadPrec (Bin a)
Int -> ReadS (Bin a)
ReadS [Bin a]
(Int -> ReadS (Bin a))
-> ReadS [Bin a]
-> ReadPrec (Bin a)
-> ReadPrec [Bin a]
-> Read (Bin a)
forall a. Read a => ReadPrec [Bin a]
forall a. Read a => ReadPrec (Bin a)
forall a. Read a => Int -> ReadS (Bin a)
forall a. Read a => ReadS [Bin a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Bin a)
readsPrec :: Int -> ReadS (Bin a)
$creadList :: forall a. Read a => ReadS [Bin a]
readList :: ReadS [Bin a]
$creadPrec :: forall a. Read a => ReadPrec (Bin a)
readPrec :: ReadPrec (Bin a)
$creadListPrec :: forall a. Read a => ReadPrec [Bin a]
readListPrec :: ReadPrec [Bin a]
Read,Eq (Bin a)
Eq (Bin a) =>
(Bin a -> Bin a -> Ordering)
-> (Bin a -> Bin a -> Bool)
-> (Bin a -> Bin a -> Bool)
-> (Bin a -> Bin a -> Bool)
-> (Bin a -> Bin a -> Bool)
-> (Bin a -> Bin a -> Bin a)
-> (Bin a -> Bin a -> Bin a)
-> Ord (Bin a)
Bin a -> Bin a -> Bool
Bin a -> Bin a -> Ordering
Bin a -> Bin a -> Bin a
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 a. Ord a => Eq (Bin a)
forall a. Ord a => Bin a -> Bin a -> Bool
forall a. Ord a => Bin a -> Bin a -> Ordering
forall a. Ord a => Bin a -> Bin a -> Bin a
$ccompare :: forall a. Ord a => Bin a -> Bin a -> Ordering
compare :: Bin a -> Bin a -> Ordering
$c< :: forall a. Ord a => Bin a -> Bin a -> Bool
< :: Bin a -> Bin a -> Bool
$c<= :: forall a. Ord a => Bin a -> Bin a -> Bool
<= :: Bin a -> Bin a -> Bool
$c> :: forall a. Ord a => Bin a -> Bin a -> Bool
> :: Bin a -> Bin a -> Bool
$c>= :: forall a. Ord a => Bin a -> Bin a -> Bool
>= :: Bin a -> Bin a -> Bool
$cmax :: forall a. Ord a => Bin a -> Bin a -> Bin a
max :: Bin a -> Bin a -> Bin a
$cmin :: forall a. Ord a => Bin a -> Bin a -> Bin a
min :: Bin a -> Bin a -> Bin a
Ord,Typeable,Int -> Bin a
Bin a -> Int
Bin a -> [Bin a]
Bin a -> Bin a
Bin a -> Bin a -> [Bin a]
Bin a -> Bin a -> Bin a -> [Bin a]
(Bin a -> Bin a)
-> (Bin a -> Bin a)
-> (Int -> Bin a)
-> (Bin a -> Int)
-> (Bin a -> [Bin a])
-> (Bin a -> Bin a -> [Bin a])
-> (Bin a -> Bin a -> [Bin a])
-> (Bin a -> Bin a -> Bin a -> [Bin a])
-> Enum (Bin a)
forall a. Enum a => Int -> Bin a
forall a. Enum a => Bin a -> Int
forall a. Enum a => Bin a -> [Bin a]
forall a. Enum a => Bin a -> Bin a
forall a. Enum a => Bin a -> Bin a -> [Bin a]
forall a. Enum a => Bin a -> Bin a -> Bin a -> [Bin a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => Bin a -> Bin a
succ :: Bin a -> Bin a
$cpred :: forall a. Enum a => Bin a -> Bin a
pred :: Bin a -> Bin a
$ctoEnum :: forall a. Enum a => Int -> Bin a
toEnum :: Int -> Bin a
$cfromEnum :: forall a. Enum a => Bin a -> Int
fromEnum :: Bin a -> Int
$cenumFrom :: forall a. Enum a => Bin a -> [Bin a]
enumFrom :: Bin a -> [Bin a]
$cenumFromThen :: forall a. Enum a => Bin a -> Bin a -> [Bin a]
enumFromThen :: Bin a -> Bin a -> [Bin a]
$cenumFromTo :: forall a. Enum a => Bin a -> Bin a -> [Bin a]
enumFromTo :: Bin a -> Bin a -> [Bin a]
$cenumFromThenTo :: forall a. Enum a => Bin a -> Bin a -> Bin a -> [Bin a]
enumFromThenTo :: Bin a -> Bin a -> Bin a -> [Bin a]
Enum)


instance (Ser.Serialize a) => DynVal (Bin a) where
    type DynRep (Bin a) = DynBinary
    toRep :: Bin a -> DynRep (Bin a)
toRep (Bin a
i) = ByteString -> DynBinary
DynBinary (a -> ByteString
forall a. Serialize a => a -> ByteString
Ser.encode a
i)
    fromRep :: DynRep (Bin a) -> Maybe (Bin a)
fromRep (DynBinary ByteString
i) = (String -> Maybe (Bin a))
-> (a -> Maybe (Bin a)) -> Either String a -> Maybe (Bin a)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe (Bin a) -> String -> Maybe (Bin a)
forall a b. a -> b -> a
const Maybe (Bin a)
forall a. Maybe a
Nothing) (Bin a -> Maybe (Bin a)
forall a. a -> Maybe a
Just (Bin a -> Maybe (Bin a)) -> (a -> Bin a) -> a -> Maybe (Bin a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bin a
forall a. a -> Bin a
Bin) (Either String a -> Maybe (Bin a))
-> Either String a -> Maybe (Bin a)
forall a b. (a -> b) -> a -> b
$
                            ByteString -> Either String a
forall a. Serialize a => ByteString -> Either String a
Ser.decode ByteString
i

newtype OldBool = OldBool Bool

instance DynVal OldBool where
    type DynRep OldBool = DynNumber
    fromRep :: DynRep OldBool -> Maybe OldBool
fromRep (DynNumber Scientific
i) = Bool -> OldBool
OldBool (Bool -> OldBool) -> Maybe Bool -> Maybe OldBool
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` do
        (Int
i' :: Int) <- Scientific -> Maybe Int
forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral Scientific
i
        case Int
i' of
          Int
0 -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
          Int
1 -> Bool -> Maybe Bool
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
          Int
_ -> Maybe Bool
forall a. Maybe a
Nothing
    toRep :: OldBool -> DynRep OldBool
toRep (OldBool Bool
b) = Scientific -> DynNumber
DynNumber (if Bool
b then Scientific
1 else Scientific
0)


-------------------------------------------------------------------------------
-- | Encode a Haskell value.
toValue :: DynVal a  => a -> DValue
toValue :: forall a. DynVal a => a -> DValue
toValue a
a = DynRep a -> DValue
forall a. DynData a => a -> DValue
fromData (DynRep a -> DValue) -> DynRep a -> DValue
forall a b. (a -> b) -> a -> b
$ a -> DynRep a
forall a. DynVal a => a -> DynRep a
toRep a
a


-------------------------------------------------------------------------------
-- | Decode a Haskell value.
fromValue :: DynVal a => DValue -> Maybe a
fromValue :: forall a. DynVal a => DValue -> Maybe a
fromValue DValue
d = DValue -> Maybe (DynRep a)
forall a. DynData a => DValue -> Maybe a
toData DValue
d Maybe (DynRep a) -> (DynRep a -> Maybe a) -> Maybe a
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DynRep a -> Maybe a
forall a. DynVal a => DynRep a -> Maybe a
fromRep


toIntegral :: (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral :: forall a a1. (Integral a, RealFrac a1) => a1 -> Maybe a
toIntegral a1
sc = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ a1 -> a
forall b. Integral b => a1 -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor a1
sc



-- | Value types natively recognized by DynamoDb. We pretty much
-- exactly reflect the AWS API onto Haskell types.
data DValue
    = DNull
    | DNum Scientific
    | DString T.Text
    | DBinary B.ByteString
    -- ^ Binary data will automatically be base64 marshalled.
    | DNumSet (S.Set Scientific)
    | DStringSet (S.Set T.Text)
    | DBinSet (S.Set B.ByteString)
    -- ^ Binary data will automatically be base64 marshalled.
    | DBool Bool
    | DBoolSet (S.Set Bool)
    -- ^ Composite data
    | DList (V.Vector DValue)
    | DMap (M.Map T.Text DValue)
    deriving (DValue -> DValue -> Bool
(DValue -> DValue -> Bool)
-> (DValue -> DValue -> Bool) -> Eq DValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DValue -> DValue -> Bool
== :: DValue -> DValue -> Bool
$c/= :: DValue -> DValue -> Bool
/= :: DValue -> DValue -> Bool
Eq,Int -> DValue -> ShowS
[DValue] -> ShowS
DValue -> String
(Int -> DValue -> ShowS)
-> (DValue -> String) -> ([DValue] -> ShowS) -> Show DValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DValue -> ShowS
showsPrec :: Int -> DValue -> ShowS
$cshow :: DValue -> String
show :: DValue -> String
$cshowList :: [DValue] -> ShowS
showList :: [DValue] -> ShowS
Show,ReadPrec [DValue]
ReadPrec DValue
Int -> ReadS DValue
ReadS [DValue]
(Int -> ReadS DValue)
-> ReadS [DValue]
-> ReadPrec DValue
-> ReadPrec [DValue]
-> Read DValue
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DValue
readsPrec :: Int -> ReadS DValue
$creadList :: ReadS [DValue]
readList :: ReadS [DValue]
$creadPrec :: ReadPrec DValue
readPrec :: ReadPrec DValue
$creadListPrec :: ReadPrec [DValue]
readListPrec :: ReadPrec [DValue]
Read,Eq DValue
Eq DValue =>
(DValue -> DValue -> Ordering)
-> (DValue -> DValue -> Bool)
-> (DValue -> DValue -> Bool)
-> (DValue -> DValue -> Bool)
-> (DValue -> DValue -> Bool)
-> (DValue -> DValue -> DValue)
-> (DValue -> DValue -> DValue)
-> Ord DValue
DValue -> DValue -> Bool
DValue -> DValue -> Ordering
DValue -> DValue -> DValue
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
$ccompare :: DValue -> DValue -> Ordering
compare :: DValue -> DValue -> Ordering
$c< :: DValue -> DValue -> Bool
< :: DValue -> DValue -> Bool
$c<= :: DValue -> DValue -> Bool
<= :: DValue -> DValue -> Bool
$c> :: DValue -> DValue -> Bool
> :: DValue -> DValue -> Bool
$c>= :: DValue -> DValue -> Bool
>= :: DValue -> DValue -> Bool
$cmax :: DValue -> DValue -> DValue
max :: DValue -> DValue -> DValue
$cmin :: DValue -> DValue -> DValue
min :: DValue -> DValue -> DValue
Ord,Typeable)


instance IsString DValue where
    fromString :: String -> DValue
fromString String
t = Text -> DValue
DString (String -> Text
T.pack String
t)

-------------------------------------------------------------------------------
-- | Primary keys consist of either just a Hash key (mandatory) or a
-- hash key and a range key (optional).
data PrimaryKey = PrimaryKey {
      PrimaryKey -> Attribute
pkHash  :: Attribute
    , PrimaryKey -> Maybe Attribute
pkRange :: Maybe Attribute
    } deriving (ReadPrec [PrimaryKey]
ReadPrec PrimaryKey
Int -> ReadS PrimaryKey
ReadS [PrimaryKey]
(Int -> ReadS PrimaryKey)
-> ReadS [PrimaryKey]
-> ReadPrec PrimaryKey
-> ReadPrec [PrimaryKey]
-> Read PrimaryKey
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS PrimaryKey
readsPrec :: Int -> ReadS PrimaryKey
$creadList :: ReadS [PrimaryKey]
readList :: ReadS [PrimaryKey]
$creadPrec :: ReadPrec PrimaryKey
readPrec :: ReadPrec PrimaryKey
$creadListPrec :: ReadPrec [PrimaryKey]
readListPrec :: ReadPrec [PrimaryKey]
Read,Int -> PrimaryKey -> ShowS
[PrimaryKey] -> ShowS
PrimaryKey -> String
(Int -> PrimaryKey -> ShowS)
-> (PrimaryKey -> String)
-> ([PrimaryKey] -> ShowS)
-> Show PrimaryKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PrimaryKey -> ShowS
showsPrec :: Int -> PrimaryKey -> ShowS
$cshow :: PrimaryKey -> String
show :: PrimaryKey -> String
$cshowList :: [PrimaryKey] -> ShowS
showList :: [PrimaryKey] -> ShowS
Show,Eq PrimaryKey
Eq PrimaryKey =>
(PrimaryKey -> PrimaryKey -> Ordering)
-> (PrimaryKey -> PrimaryKey -> Bool)
-> (PrimaryKey -> PrimaryKey -> Bool)
-> (PrimaryKey -> PrimaryKey -> Bool)
-> (PrimaryKey -> PrimaryKey -> Bool)
-> (PrimaryKey -> PrimaryKey -> PrimaryKey)
-> (PrimaryKey -> PrimaryKey -> PrimaryKey)
-> Ord PrimaryKey
PrimaryKey -> PrimaryKey -> Bool
PrimaryKey -> PrimaryKey -> Ordering
PrimaryKey -> PrimaryKey -> PrimaryKey
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
$ccompare :: PrimaryKey -> PrimaryKey -> Ordering
compare :: PrimaryKey -> PrimaryKey -> Ordering
$c< :: PrimaryKey -> PrimaryKey -> Bool
< :: PrimaryKey -> PrimaryKey -> Bool
$c<= :: PrimaryKey -> PrimaryKey -> Bool
<= :: PrimaryKey -> PrimaryKey -> Bool
$c> :: PrimaryKey -> PrimaryKey -> Bool
> :: PrimaryKey -> PrimaryKey -> Bool
$c>= :: PrimaryKey -> PrimaryKey -> Bool
>= :: PrimaryKey -> PrimaryKey -> Bool
$cmax :: PrimaryKey -> PrimaryKey -> PrimaryKey
max :: PrimaryKey -> PrimaryKey -> PrimaryKey
$cmin :: PrimaryKey -> PrimaryKey -> PrimaryKey
min :: PrimaryKey -> PrimaryKey -> PrimaryKey
Ord,PrimaryKey -> PrimaryKey -> Bool
(PrimaryKey -> PrimaryKey -> Bool)
-> (PrimaryKey -> PrimaryKey -> Bool) -> Eq PrimaryKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PrimaryKey -> PrimaryKey -> Bool
== :: PrimaryKey -> PrimaryKey -> Bool
$c/= :: PrimaryKey -> PrimaryKey -> Bool
/= :: PrimaryKey -> PrimaryKey -> Bool
Eq,Typeable)


-------------------------------------------------------------------------------
-- | Construct a hash-only primary key.
--
-- >>> hk "user-id" "ABCD"
--
-- >>> hk "user-id" (mkVal 23)
hk :: T.Text -> DValue -> PrimaryKey
hk :: Text -> DValue -> PrimaryKey
hk Text
k DValue
v = Attribute -> Maybe Attribute -> PrimaryKey
PrimaryKey (Text -> DValue -> Attribute
forall a. DynVal a => Text -> a -> Attribute
attr Text
k DValue
v) Maybe Attribute
forall a. Maybe a
Nothing


-------------------------------------------------------------------------------
-- | Construct a hash-and-range primary key.
hrk :: T.Text                   -- ^ Hash key name
    -> DValue                   -- ^ Hash key value
    -> T.Text                   -- ^ Range key name
    -> DValue                   -- ^ Range key value
    -> PrimaryKey
hrk :: Text -> DValue -> Text -> DValue -> PrimaryKey
hrk Text
k DValue
v Text
k2 DValue
v2 = Attribute -> Maybe Attribute -> PrimaryKey
PrimaryKey (Text -> DValue -> Attribute
forall a. DynVal a => Text -> a -> Attribute
attr Text
k DValue
v) (Attribute -> Maybe Attribute
forall a. a -> Maybe a
Just (Text -> DValue -> Attribute
forall a. DynVal a => Text -> a -> Attribute
attr Text
k2 DValue
v2))


instance ToJSON PrimaryKey where
    toJSON :: PrimaryKey -> Value
toJSON (PrimaryKey Attribute
h Maybe Attribute
Nothing) = Attribute -> Value
forall a. ToJSON a => a -> Value
toJSON Attribute
h
    toJSON (PrimaryKey Attribute
h (Just Attribute
r)) =
      let Object Object
p1 = Attribute -> Value
forall a. ToJSON a => a -> Value
toJSON Attribute
h
          Object Object
p2 = Attribute -> Value
forall a. ToJSON a => a -> Value
toJSON Attribute
r
      in Object -> Value
Object (Object
p1 Object -> Object -> Object
forall v. KeyMap v -> KeyMap v -> KeyMap v
`KM.union` Object
p2)

instance FromJSON PrimaryKey where
    parseJSON :: Value -> Parser PrimaryKey
parseJSON Value
p = do
       [PrimaryKey]
l <- Value -> Parser [PrimaryKey]
listPKey Value
p
       case [PrimaryKey] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PrimaryKey]
l of
          Int
1 -> PrimaryKey -> Parser PrimaryKey
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (PrimaryKey -> Parser PrimaryKey)
-> PrimaryKey -> Parser PrimaryKey
forall a b. (a -> b) -> a -> b
$ [PrimaryKey] -> PrimaryKey
forall a. HasCallStack => [a] -> a
head [PrimaryKey]
l 
          Int
_ -> String -> Parser PrimaryKey
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unable to parse PrimaryKey"     
      where listPKey :: Value -> Parser [PrimaryKey]
listPKey Value
p'= ((Key, DValue) -> PrimaryKey) -> [(Key, DValue)] -> [PrimaryKey]
forall a b. (a -> b) -> [a] -> [b]
map (\(Key
k,DValue
dval)-> Text -> DValue -> PrimaryKey
hk (Key -> Text
AK.toText Key
k) DValue
dval)
                          ([(Key, DValue)] -> [PrimaryKey])
-> (KeyMap DValue -> [(Key, DValue)])
-> KeyMap DValue
-> [PrimaryKey]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyMap DValue -> [(Key, DValue)]
forall v. KeyMap v -> [(Key, v)]
KM.toList (KeyMap DValue -> [PrimaryKey])
-> Parser (KeyMap DValue) -> Parser [PrimaryKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (KeyMap DValue)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
p'


-- | A key-value pair
data Attribute = Attribute {
      Attribute -> Text
attrName :: T.Text
    , Attribute -> DValue
attrVal  :: DValue
    } deriving (ReadPrec [Attribute]
ReadPrec Attribute
Int -> ReadS Attribute
ReadS [Attribute]
(Int -> ReadS Attribute)
-> ReadS [Attribute]
-> ReadPrec Attribute
-> ReadPrec [Attribute]
-> Read Attribute
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Attribute
readsPrec :: Int -> ReadS Attribute
$creadList :: ReadS [Attribute]
readList :: ReadS [Attribute]
$creadPrec :: ReadPrec Attribute
readPrec :: ReadPrec Attribute
$creadListPrec :: ReadPrec [Attribute]
readListPrec :: ReadPrec [Attribute]
Read,Int -> Attribute -> ShowS
[Attribute] -> ShowS
Attribute -> String
(Int -> Attribute -> ShowS)
-> (Attribute -> String)
-> ([Attribute] -> ShowS)
-> Show Attribute
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Attribute -> ShowS
showsPrec :: Int -> Attribute -> ShowS
$cshow :: Attribute -> String
show :: Attribute -> String
$cshowList :: [Attribute] -> ShowS
showList :: [Attribute] -> ShowS
Show,Eq Attribute
Eq Attribute =>
(Attribute -> Attribute -> Ordering)
-> (Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Attribute)
-> (Attribute -> Attribute -> Attribute)
-> Ord Attribute
Attribute -> Attribute -> Bool
Attribute -> Attribute -> Ordering
Attribute -> Attribute -> Attribute
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
$ccompare :: Attribute -> Attribute -> Ordering
compare :: Attribute -> Attribute -> Ordering
$c< :: Attribute -> Attribute -> Bool
< :: Attribute -> Attribute -> Bool
$c<= :: Attribute -> Attribute -> Bool
<= :: Attribute -> Attribute -> Bool
$c> :: Attribute -> Attribute -> Bool
> :: Attribute -> Attribute -> Bool
$c>= :: Attribute -> Attribute -> Bool
>= :: Attribute -> Attribute -> Bool
$cmax :: Attribute -> Attribute -> Attribute
max :: Attribute -> Attribute -> Attribute
$cmin :: Attribute -> Attribute -> Attribute
min :: Attribute -> Attribute -> Attribute
Ord,Attribute -> Attribute -> Bool
(Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Bool) -> Eq Attribute
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Attribute -> Attribute -> Bool
== :: Attribute -> Attribute -> Bool
$c/= :: Attribute -> Attribute -> Bool
/= :: Attribute -> Attribute -> Bool
Eq,Typeable)


-- | Convert attribute to a tuple representation
attrTuple :: Attribute -> (T.Text, DValue)
attrTuple :: Attribute -> (Text, DValue)
attrTuple (Attribute Text
a DValue
b) = (Text
a,DValue
b)


-- | Convenience function for constructing key-value pairs
attr :: DynVal a => T.Text -> a -> Attribute
attr :: forall a. DynVal a => Text -> a -> Attribute
attr Text
k a
v = Text -> DValue -> Attribute
Attribute Text
k (a -> DValue
forall a. DynVal a => a -> DValue
toValue a
v)


-- | 'attr' with type witness to help with cases where you're manually
-- supplying values in code.
--
-- >> item [ attrAs text "name" "john" ]
attrAs :: DynVal a => Proxy a -> T.Text -> a -> Attribute
attrAs :: forall a. DynVal a => Proxy a -> Text -> a -> Attribute
attrAs Proxy a
_ Text
k a
v = Text -> a -> Attribute
forall a. DynVal a => Text -> a -> Attribute
attr Text
k a
v


-- | Type witness for 'Text'. See 'attrAs'.
text :: Proxy T.Text
text :: Proxy Text
text = Proxy Text
forall {k} (t :: k). Proxy t
Proxy


-- | Type witness for 'Integer'. See 'attrAs'.
int :: Proxy Integer
int :: Proxy Integer
int = Proxy Integer
forall {k} (t :: k). Proxy t
Proxy


-- | Type witness for 'Double'. See 'attrAs'.
double :: Proxy Double
double :: Proxy Double
double = Proxy Double
forall {k} (t :: k). Proxy t
Proxy


-- | A DynamoDb object is simply a key-value dictionary.
type Item = M.Map T.Text DValue


-------------------------------------------------------------------------------
-- | Pack a list of attributes into an Item.
item :: [Attribute] -> Item
item :: [Attribute] -> Map Text DValue
item = [(Text, DValue)] -> Map Text DValue
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, DValue)] -> Map Text DValue)
-> ([Attribute] -> [(Text, DValue)])
-> [Attribute]
-> Map Text DValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Attribute -> (Text, DValue)) -> [Attribute] -> [(Text, DValue)]
forall a b. (a -> b) -> [a] -> [b]
map Attribute -> (Text, DValue)
attrTuple


-------------------------------------------------------------------------------
-- | Unpack an 'Item' into a list of attributes.
attributes :: M.Map T.Text DValue -> [Attribute]
attributes :: Map Text DValue -> [Attribute]
attributes = ((Text, DValue) -> Attribute) -> [(Text, DValue)] -> [Attribute]
forall a b. (a -> b) -> [a] -> [b]
map (\ (Text
k, DValue
v) -> Text -> DValue -> Attribute
Attribute Text
k DValue
v) ([(Text, DValue)] -> [Attribute])
-> (Map Text DValue -> [(Text, DValue)])
-> Map Text DValue
-> [Attribute]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Text DValue -> [(Text, DValue)]
forall k a. Map k a -> [(k, a)]
M.toList


showT :: Show a => a -> T.Text
showT :: forall a. Show a => a -> Text
showT = String -> Text
T.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show


instance ToJSON DValue where
    toJSON :: DValue -> Value
toJSON DValue
DNull = [Pair] -> Value
object [Key
"NULL" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Bool
True]
    toJSON (DNum Scientific
i) = [Pair] -> Value
object [Key
"N" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Scientific -> Text
forall a. Show a => a -> Text
showT Scientific
i]
    toJSON (DString Text
i) = [Pair] -> Value
object [Key
"S" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
i]
    toJSON (DBinary ByteString
i) = [Pair] -> Value
object [Key
"B" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (ByteString -> Text
T.decodeUtf8 (ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
Base64.encode ByteString
i)]
    toJSON (DNumSet Set Scientific
i) = [Pair] -> Value
object [Key
"NS" Key -> [Text] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (Scientific -> Text) -> [Scientific] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Scientific -> Text
forall a. Show a => a -> Text
showT (Set Scientific -> [Scientific]
forall a. Set a -> [a]
S.toList Set Scientific
i)]
    toJSON (DStringSet Set Text
i) = [Pair] -> Value
object [Key
"SS" Key -> [Text] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Set Text -> [Text]
forall a. Set a -> [a]
S.toList Set Text
i]
    toJSON (DBinSet Set ByteString
i) = [Pair] -> Value
object [Key
"BS" Key -> [Text] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= (ByteString -> Text) -> [ByteString] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (ByteString -> Text
T.decodeUtf8 (ByteString -> Text)
-> (ByteString -> ByteString) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
Base64.encode) (Set ByteString -> [ByteString]
forall a. Set a -> [a]
S.toList Set ByteString
i)]
    toJSON (DBool Bool
i) = [Pair] -> Value
object [Key
"BOOL" Key -> Bool -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Bool
i]
    toJSON (DList Vector DValue
i) = [Pair] -> Value
object [Key
"L" Key -> Vector DValue -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Vector DValue
i]
    toJSON (DMap Map Text DValue
i) = [Pair] -> Value
object [Key
"M" Key -> Map Text DValue -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Map Text DValue
i]
    toJSON DValue
x = String -> Value
forall a. HasCallStack => String -> a
error (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ String
"aws: bug: DynamoDB can't handle " String -> ShowS
forall a. [a] -> [a] -> [a]
++ DValue -> String
forall a. Show a => a -> String
show DValue
x


instance FromJSON DValue where
    parseJSON :: Value -> Parser DValue
parseJSON Value
o = do
      ([(Text, Value)]
obj :: [(T.Text, Value)]) <- Map Text Value -> [(Text, Value)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Text Value -> [(Text, Value)])
-> Parser (Map Text Value) -> Parser [(Text, Value)]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` Value -> Parser (Map Text Value)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
o
      case [(Text, Value)]
obj of
        [(Text
"NULL", Value
_)] -> DValue -> Parser DValue
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return DValue
DNull
        [(Text
"N", Value
numStr)] -> Scientific -> DValue
DNum (Scientific -> DValue) -> Parser Scientific -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Scientific
forall {m :: * -> *}. MonadFail m => Value -> m Scientific
parseScientific Value
numStr
        [(Text
"S", Value
str)] -> Text -> DValue
DString (Text -> DValue) -> Parser Text -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
str
        [(Text
"B", Value
bin)] -> do
            Either String ByteString
res <- (ByteString -> Either String ByteString
Base64.decode (ByteString -> Either String ByteString)
-> (Text -> ByteString) -> Text -> Either String ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8) (Text -> Either String ByteString)
-> Parser Text -> Parser (Either String ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
bin
            (String -> Parser DValue)
-> (ByteString -> Parser DValue)
-> Either String ByteString
-> Parser DValue
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Parser DValue
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (DValue -> Parser DValue
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (DValue -> Parser DValue)
-> (ByteString -> DValue) -> ByteString -> Parser DValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> DValue
DBinary) Either String ByteString
res
        [(Text
"NS", Value
s)] -> do [Scientific]
xs <- (Value -> Parser Scientific) -> [Value] -> Parser [Scientific]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Value -> Parser Scientific
forall {m :: * -> *}. MonadFail m => Value -> m Scientific
parseScientific ([Value] -> Parser [Scientific])
-> Parser [Value] -> Parser [Scientific]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value -> Parser [Value]
forall a. FromJSON a => Value -> Parser a
parseJSON Value
s
                          DValue -> Parser DValue
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (DValue -> Parser DValue) -> DValue -> Parser DValue
forall a b. (a -> b) -> a -> b
$ Set Scientific -> DValue
DNumSet (Set Scientific -> DValue) -> Set Scientific -> DValue
forall a b. (a -> b) -> a -> b
$ [Scientific] -> Set Scientific
forall a. Ord a => [a] -> Set a
S.fromList [Scientific]
xs
        [(Text
"SS", Value
s)] -> Set Text -> DValue
DStringSet (Set Text -> DValue) -> Parser (Set Text) -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Set Text)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
s
        [(Text
"BS", Value
s)] -> do
            [ByteString]
xs <- (Text -> Parser ByteString) -> [Text] -> Parser [ByteString]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM ((String -> Parser ByteString)
-> (ByteString -> Parser ByteString)
-> Either String ByteString
-> Parser ByteString
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Parser ByteString
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail ByteString -> Parser ByteString
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String ByteString -> Parser ByteString)
-> (Text -> Either String ByteString) -> Text -> Parser ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String ByteString
Base64.decode (ByteString -> Either String ByteString)
-> (Text -> ByteString) -> Text -> Either String ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8)
                  ([Text] -> Parser [ByteString])
-> Parser [Text] -> Parser [ByteString]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Value -> Parser [Text]
forall a. FromJSON a => Value -> Parser a
parseJSON Value
s
            DValue -> Parser DValue
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (DValue -> Parser DValue) -> DValue -> Parser DValue
forall a b. (a -> b) -> a -> b
$ Set ByteString -> DValue
DBinSet (Set ByteString -> DValue) -> Set ByteString -> DValue
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Set ByteString
forall a. Ord a => [a] -> Set a
S.fromList [ByteString]
xs
        [(Text
"BOOL", Value
b)] -> Bool -> DValue
DBool (Bool -> DValue) -> Parser Bool -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Bool
forall a. FromJSON a => Value -> Parser a
parseJSON Value
b
        [(Text
"L", Value
attrs)] -> Vector DValue -> DValue
DList (Vector DValue -> DValue)
-> Parser (Vector DValue) -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Vector DValue)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
attrs
        [(Text
"M", Value
attrs)] -> Map Text DValue -> DValue
DMap (Map Text DValue -> DValue)
-> Parser (Map Text DValue) -> Parser DValue
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser (Map Text DValue)
forall a. FromJSON a => Value -> Parser a
parseJSON Value
attrs

        [(Text, Value)]
x -> String -> Parser DValue
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser DValue) -> String -> Parser DValue
forall a b. (a -> b) -> a -> b
$ String
"aws: unknown dynamodb value: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [(Text, Value)] -> String
forall a. Show a => a -> String
show [(Text, Value)]
x

      where
        parseScientific :: Value -> m Scientific
parseScientific (String Text
str) =
            case Parser Scientific -> Text -> Either String Scientific
forall a. Parser a -> Text -> Either String a
Atto.parseOnly Parser Scientific
Atto.scientific Text
str of
              Left String
e -> String -> m Scientific
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"parseScientific failed: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
e)
              Right Scientific
a -> Scientific -> m Scientific
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Scientific
a
        parseScientific (Number Scientific
n) = Scientific -> m Scientific
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Scientific
n
        parseScientific Value
_ = String -> m Scientific
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Unexpected JSON type in parseScientific"


instance ToJSON Attribute where
    toJSON :: Attribute -> Value
toJSON Attribute
a = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [Attribute -> Pair
attributeJson Attribute
a]


-------------------------------------------------------------------------------
-- | Parse a JSON object that contains attributes
parseAttributeJson :: Value -> A.Parser [Attribute]
parseAttributeJson :: Value -> Parser [Attribute]
parseAttributeJson (Object Object
v) = (Pair -> Parser Attribute) -> [Pair] -> Parser [Attribute]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Pair -> Parser Attribute
conv ([Pair] -> Parser [Attribute]) -> [Pair] -> Parser [Attribute]
forall a b. (a -> b) -> a -> b
$ Object -> [Pair]
forall v. KeyMap v -> [(Key, v)]
KM.toList Object
v
    where
      conv :: Pair -> Parser Attribute
conv (Key
k, Value
o) = Text -> DValue -> Attribute
Attribute (Key -> Text
AK.toText Key
k) (DValue -> Attribute) -> Parser DValue -> Parser Attribute
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser DValue
forall a. FromJSON a => Value -> Parser a
parseJSON Value
o
parseAttributeJson Value
_ = String -> Parser [Attribute]
forall a. HasCallStack => String -> a
error String
"Attribute JSON must be an Object"


-- | Convert into JSON object for AWS.
attributesJson :: [Attribute] -> Value
attributesJson :: [Attribute] -> Value
attributesJson [Attribute]
as = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ (Attribute -> Pair) -> [Attribute] -> [Pair]
forall a b. (a -> b) -> [a] -> [b]
map Attribute -> Pair
attributeJson [Attribute]
as


-- | Convert into JSON pair
attributeJson :: Attribute -> Pair
attributeJson :: Attribute -> Pair
attributeJson (Attribute Text
nm DValue
v) = Text -> Key
AK.fromText Text
nm Key -> DValue -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= DValue
v


-------------------------------------------------------------------------------
-- | Errors defined by AWS.
data DdbErrCode
    = AccessDeniedException
    | ConditionalCheckFailedException
    | IncompleteSignatureException
    | InvalidSignatureException
    | LimitExceededException
    | MissingAuthenticationTokenException
    | ProvisionedThroughputExceededException
    | ResourceInUseException
    | ResourceNotFoundException
    | ThrottlingException
    | ValidationException
    | RequestTooLarge
    | InternalFailure
    | InternalServerError
    | ServiceUnavailableException
    | SerializationException
    -- ^ Raised by AWS when the request JSON is missing fields or is
    -- somehow malformed.
    deriving (ReadPrec [DdbErrCode]
ReadPrec DdbErrCode
Int -> ReadS DdbErrCode
ReadS [DdbErrCode]
(Int -> ReadS DdbErrCode)
-> ReadS [DdbErrCode]
-> ReadPrec DdbErrCode
-> ReadPrec [DdbErrCode]
-> Read DdbErrCode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DdbErrCode
readsPrec :: Int -> ReadS DdbErrCode
$creadList :: ReadS [DdbErrCode]
readList :: ReadS [DdbErrCode]
$creadPrec :: ReadPrec DdbErrCode
readPrec :: ReadPrec DdbErrCode
$creadListPrec :: ReadPrec [DdbErrCode]
readListPrec :: ReadPrec [DdbErrCode]
Read,Int -> DdbErrCode -> ShowS
[DdbErrCode] -> ShowS
DdbErrCode -> String
(Int -> DdbErrCode -> ShowS)
-> (DdbErrCode -> String)
-> ([DdbErrCode] -> ShowS)
-> Show DdbErrCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DdbErrCode -> ShowS
showsPrec :: Int -> DdbErrCode -> ShowS
$cshow :: DdbErrCode -> String
show :: DdbErrCode -> String
$cshowList :: [DdbErrCode] -> ShowS
showList :: [DdbErrCode] -> ShowS
Show,DdbErrCode -> DdbErrCode -> Bool
(DdbErrCode -> DdbErrCode -> Bool)
-> (DdbErrCode -> DdbErrCode -> Bool) -> Eq DdbErrCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DdbErrCode -> DdbErrCode -> Bool
== :: DdbErrCode -> DdbErrCode -> Bool
$c/= :: DdbErrCode -> DdbErrCode -> Bool
/= :: DdbErrCode -> DdbErrCode -> Bool
Eq,Typeable)


-------------------------------------------------------------------------------
-- | Whether the action should be retried based on the received error.
shouldRetry :: DdbErrCode -> Bool
shouldRetry :: DdbErrCode -> Bool
shouldRetry DdbErrCode
e = DdbErrCode -> Bool
go DdbErrCode
e
    where
      go :: DdbErrCode -> Bool
go DdbErrCode
LimitExceededException = Bool
True
      go DdbErrCode
ProvisionedThroughputExceededException = Bool
True
      go DdbErrCode
ResourceInUseException = Bool
True
      go DdbErrCode
ThrottlingException = Bool
True
      go DdbErrCode
InternalFailure = Bool
True
      go DdbErrCode
InternalServerError = Bool
True
      go DdbErrCode
ServiceUnavailableException = Bool
True
      go DdbErrCode
_ = Bool
False


-------------------------------------------------------------------------------
-- | Errors related to this library.
data DdbLibraryError
    = UnknownDynamoErrCode T.Text
    -- ^ A DynamoDB error code we do not know about.
    | JsonProtocolError Value T.Text
    -- ^ A JSON response we could not parse.
    deriving (Int -> DdbLibraryError -> ShowS
[DdbLibraryError] -> ShowS
DdbLibraryError -> String
(Int -> DdbLibraryError -> ShowS)
-> (DdbLibraryError -> String)
-> ([DdbLibraryError] -> ShowS)
-> Show DdbLibraryError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DdbLibraryError -> ShowS
showsPrec :: Int -> DdbLibraryError -> ShowS
$cshow :: DdbLibraryError -> String
show :: DdbLibraryError -> String
$cshowList :: [DdbLibraryError] -> ShowS
showList :: [DdbLibraryError] -> ShowS
Show,DdbLibraryError -> DdbLibraryError -> Bool
(DdbLibraryError -> DdbLibraryError -> Bool)
-> (DdbLibraryError -> DdbLibraryError -> Bool)
-> Eq DdbLibraryError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DdbLibraryError -> DdbLibraryError -> Bool
== :: DdbLibraryError -> DdbLibraryError -> Bool
$c/= :: DdbLibraryError -> DdbLibraryError -> Bool
/= :: DdbLibraryError -> DdbLibraryError -> Bool
Eq,Typeable)


-- | Potential errors raised by DynamoDB
data DdbError = DdbError {
      DdbError -> Int
ddbStatusCode :: Int
    -- ^ 200 if successful, 400 for client errors and 500 for
    -- server-side errors.
    , DdbError -> DdbErrCode
ddbErrCode    :: DdbErrCode
    , DdbError -> Text
ddbErrMsg     :: T.Text
    } deriving (Int -> DdbError -> ShowS
[DdbError] -> ShowS
DdbError -> String
(Int -> DdbError -> ShowS)
-> (DdbError -> String) -> ([DdbError] -> ShowS) -> Show DdbError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DdbError -> ShowS
showsPrec :: Int -> DdbError -> ShowS
$cshow :: DdbError -> String
show :: DdbError -> String
$cshowList :: [DdbError] -> ShowS
showList :: [DdbError] -> ShowS
Show,DdbError -> DdbError -> Bool
(DdbError -> DdbError -> Bool)
-> (DdbError -> DdbError -> Bool) -> Eq DdbError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DdbError -> DdbError -> Bool
== :: DdbError -> DdbError -> Bool
$c/= :: DdbError -> DdbError -> Bool
/= :: DdbError -> DdbError -> Bool
Eq,Typeable)


instance C.Exception DdbError
instance C.Exception DdbLibraryError


-- | Response metadata that is present in every DynamoDB response.
data DdbResponse = DdbResponse {
      DdbResponse -> Maybe Text
ddbrCrc   :: Maybe T.Text
    , DdbResponse -> Maybe Text
ddbrMsgId :: Maybe T.Text
    }


instance Loggable DdbResponse where
    toLogText :: DdbResponse -> Text
toLogText (DdbResponse Maybe Text
id2 Maybe Text
rid) =
        Text
"DynamoDB: request ID=" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend`
        Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"<none>" Maybe Text
rid Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend`
        Text
", x-amz-id-2=" Text -> Text -> Text
forall a. Monoid a => a -> a -> a
`mappend`
        Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"<none>" Maybe Text
id2

instance Sem.Semigroup DdbResponse where
    DdbResponse
a <> :: DdbResponse -> DdbResponse -> DdbResponse
<> DdbResponse
b = Maybe Text -> Maybe Text -> DdbResponse
DdbResponse (DdbResponse -> Maybe Text
ddbrCrc DdbResponse
a Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` DdbResponse -> Maybe Text
ddbrCrc DdbResponse
b) (DdbResponse -> Maybe Text
ddbrMsgId DdbResponse
a Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` DdbResponse -> Maybe Text
ddbrMsgId DdbResponse
b)

instance Monoid DdbResponse where
    mempty :: DdbResponse
mempty = Maybe Text -> Maybe Text -> DdbResponse
DdbResponse Maybe Text
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing
    mappend :: DdbResponse -> DdbResponse -> DdbResponse
mappend = DdbResponse -> DdbResponse -> DdbResponse
forall a. Semigroup a => a -> a -> a
(Sem.<>)


data Region = Region {
      Region -> ByteString
rUri  :: B.ByteString
    , Region -> ByteString
rName :: B.ByteString
    } deriving (Region -> Region -> Bool
(Region -> Region -> Bool)
-> (Region -> Region -> Bool) -> Eq Region
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Region -> Region -> Bool
== :: Region -> Region -> Bool
$c/= :: Region -> Region -> Bool
/= :: Region -> Region -> Bool
Eq,Int -> Region -> ShowS
[Region] -> ShowS
Region -> String
(Int -> Region -> ShowS)
-> (Region -> String) -> ([Region] -> ShowS) -> Show Region
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Region -> ShowS
showsPrec :: Int -> Region -> ShowS
$cshow :: Region -> String
show :: Region -> String
$cshowList :: [Region] -> ShowS
showList :: [Region] -> ShowS
Show,ReadPrec [Region]
ReadPrec Region
Int -> ReadS Region
ReadS [Region]
(Int -> ReadS Region)
-> ReadS [Region]
-> ReadPrec Region
-> ReadPrec [Region]
-> Read Region
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Region
readsPrec :: Int -> ReadS Region
$creadList :: ReadS [Region]
readList :: ReadS [Region]
$creadPrec :: ReadPrec Region
readPrec :: ReadPrec Region
$creadListPrec :: ReadPrec [Region]
readListPrec :: ReadPrec [Region]
Read,Typeable)


data DdbConfiguration qt = DdbConfiguration {
      forall qt. DdbConfiguration qt -> Region
ddbcRegion   :: Region
    -- ^ The regional endpoint. Ex: 'ddbUsEast'
    , forall qt. DdbConfiguration qt -> Protocol
ddbcProtocol :: Protocol
    -- ^ 'HTTP' or 'HTTPS'
    , forall qt. DdbConfiguration qt -> Maybe Int
ddbcPort     :: Maybe Int
    -- ^ Port override (mostly for local dev connection)
    } deriving (Int -> DdbConfiguration qt -> ShowS
[DdbConfiguration qt] -> ShowS
DdbConfiguration qt -> String
(Int -> DdbConfiguration qt -> ShowS)
-> (DdbConfiguration qt -> String)
-> ([DdbConfiguration qt] -> ShowS)
-> Show (DdbConfiguration qt)
forall qt. Int -> DdbConfiguration qt -> ShowS
forall qt. [DdbConfiguration qt] -> ShowS
forall qt. DdbConfiguration qt -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall qt. Int -> DdbConfiguration qt -> ShowS
showsPrec :: Int -> DdbConfiguration qt -> ShowS
$cshow :: forall qt. DdbConfiguration qt -> String
show :: DdbConfiguration qt -> String
$cshowList :: forall qt. [DdbConfiguration qt] -> ShowS
showList :: [DdbConfiguration qt] -> ShowS
Show,Typeable)

instance Default (DdbConfiguration NormalQuery) where
    def :: DdbConfiguration NormalQuery
def = Region -> Protocol -> Maybe Int -> DdbConfiguration NormalQuery
forall qt. Region -> Protocol -> Maybe Int -> DdbConfiguration qt
DdbConfiguration Region
ddbUsEast1 Protocol
HTTPS Maybe Int
forall a. Maybe a
Nothing

instance DefaultServiceConfiguration (DdbConfiguration NormalQuery) where
  defServiceConfig :: DdbConfiguration NormalQuery
defServiceConfig = Region -> DdbConfiguration NormalQuery
ddbHttps Region
ddbUsEast1
  debugServiceConfig :: DdbConfiguration NormalQuery
debugServiceConfig = Region -> DdbConfiguration NormalQuery
ddbHttp Region
ddbUsEast1


-------------------------------------------------------------------------------
-- | DynamoDb local connection (for development)
ddbLocal :: Region
ddbLocal :: Region
ddbLocal = ByteString -> ByteString -> Region
Region ByteString
"127.0.0.1" ByteString
"local"

ddbUsEast1 :: Region
ddbUsEast1 :: Region
ddbUsEast1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.us-east-1.amazonaws.com" ByteString
"us-east-1"

ddbUsWest1 :: Region
ddbUsWest1 :: Region
ddbUsWest1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.us-west-1.amazonaws.com" ByteString
"us-west-1"

ddbUsWest2 :: Region
ddbUsWest2 :: Region
ddbUsWest2 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.us-west-2.amazonaws.com" ByteString
"us-west-2"

ddbEuWest1 :: Region
ddbEuWest1 :: Region
ddbEuWest1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.eu-west-1.amazonaws.com" ByteString
"eu-west-1"

ddbEuWest2 :: Region
ddbEuWest2 :: Region
ddbEuWest2 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.eu-west-2.amazonaws.com" ByteString
"eu-west-2"

ddbEuCentral1 :: Region
ddbEuCentral1 :: Region
ddbEuCentral1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.eu-central-1.amazonaws.com" ByteString
"eu-central-1"

ddbApNe1 :: Region
ddbApNe1 :: Region
ddbApNe1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.ap-northeast-1.amazonaws.com" ByteString
"ap-northeast-1"

ddbApSe1 :: Region
ddbApSe1 :: Region
ddbApSe1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.ap-southeast-1.amazonaws.com" ByteString
"ap-southeast-1"

ddbApSe2 :: Region
ddbApSe2 :: Region
ddbApSe2 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.ap-southeast-2.amazonaws.com" ByteString
"ap-southeast-2"

ddbSaEast1 :: Region
ddbSaEast1 :: Region
ddbSaEast1 = ByteString -> ByteString -> Region
Region ByteString
"dynamodb.sa-east-1.amazonaws.com" ByteString
"sa-east-1"

ddbHttp :: Region -> DdbConfiguration NormalQuery
ddbHttp :: Region -> DdbConfiguration NormalQuery
ddbHttp Region
endpoint = Region -> Protocol -> Maybe Int -> DdbConfiguration NormalQuery
forall qt. Region -> Protocol -> Maybe Int -> DdbConfiguration qt
DdbConfiguration Region
endpoint Protocol
HTTP Maybe Int
forall a. Maybe a
Nothing

ddbHttps :: Region -> DdbConfiguration NormalQuery
ddbHttps :: Region -> DdbConfiguration NormalQuery
ddbHttps Region
endpoint = Region -> Protocol -> Maybe Int -> DdbConfiguration NormalQuery
forall qt. Region -> Protocol -> Maybe Int -> DdbConfiguration qt
DdbConfiguration Region
endpoint Protocol
HTTPS Maybe Int
forall a. Maybe a
Nothing


ddbSignQuery
    :: A.ToJSON a
    => B.ByteString
    -> a
    -> DdbConfiguration qt
    -> SignatureData
    -> SignedQuery
ddbSignQuery :: forall a qt.
ToJSON a =>
ByteString
-> a -> DdbConfiguration qt -> SignatureData -> SignedQuery
ddbSignQuery ByteString
target a
body DdbConfiguration qt
di SignatureData
sd
    = SignedQuery {
        sqMethod :: Method
sqMethod = Method
Post
      , sqProtocol :: Protocol
sqProtocol = DdbConfiguration qt -> Protocol
forall qt. DdbConfiguration qt -> Protocol
ddbcProtocol DdbConfiguration qt
di
      , sqHost :: ByteString
sqHost = ByteString
host
      , sqPort :: Int
sqPort = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Protocol -> Int
defaultPort (DdbConfiguration qt -> Protocol
forall qt. DdbConfiguration qt -> Protocol
ddbcProtocol DdbConfiguration qt
di)) (DdbConfiguration qt -> Maybe Int
forall qt. DdbConfiguration qt -> Maybe Int
ddbcPort DdbConfiguration qt
di)
      , sqPath :: ByteString
sqPath = ByteString
"/"
      , sqQuery :: Query
sqQuery = []
      , sqDate :: Maybe UTCTime
sqDate = UTCTime -> Maybe UTCTime
forall a. a -> Maybe a
Just (UTCTime -> Maybe UTCTime) -> UTCTime -> Maybe UTCTime
forall a b. (a -> b) -> a -> b
$ SignatureData -> UTCTime
signatureTime SignatureData
sd
      , sqAuthorization :: Maybe (IO ByteString)
sqAuthorization = IO ByteString -> Maybe (IO ByteString)
forall a. a -> Maybe a
Just IO ByteString
auth
      , sqContentType :: Maybe ByteString
sqContentType = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
"application/x-amz-json-1.0"
      , sqContentMd5 :: Maybe (Digest MD5)
sqContentMd5 = Maybe (Digest MD5)
forall a. Maybe a
Nothing
      , sqAmzHeaders :: RequestHeaders
sqAmzHeaders = RequestHeaders
amzHeaders RequestHeaders -> RequestHeaders -> RequestHeaders
forall a. [a] -> [a] -> [a]
++ RequestHeaders
-> (ByteString -> RequestHeaders)
-> Maybe ByteString
-> RequestHeaders
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\ByteString
tok -> [(CI ByteString
"x-amz-security-token",ByteString
tok)]) (Credentials -> Maybe ByteString
iamToken Credentials
credentials)
      , sqOtherHeaders :: RequestHeaders
sqOtherHeaders = []
      , sqBody :: Maybe RequestBody
sqBody = RequestBody -> Maybe RequestBody
forall a. a -> Maybe a
Just (RequestBody -> Maybe RequestBody)
-> RequestBody -> Maybe RequestBody
forall a b. (a -> b) -> a -> b
$ ByteString -> RequestBody
HTTP.RequestBodyLBS ByteString
bodyLBS
      , sqStringToSign :: ByteString
sqStringToSign = ByteString
canonicalRequest
      }
    where
        credentials :: Credentials
credentials = SignatureData -> Credentials
signatureCredentials SignatureData
sd

        Region{ByteString
rUri :: Region -> ByteString
rName :: Region -> ByteString
rUri :: ByteString
rName :: ByteString
..} = DdbConfiguration qt -> Region
forall qt. DdbConfiguration qt -> Region
ddbcRegion DdbConfiguration qt
di
        host :: ByteString
host = ByteString
rUri

        sigTime :: ByteString
sigTime = String -> UTCTime -> ByteString
fmtTime String
"%Y%m%dT%H%M%SZ" (UTCTime -> ByteString) -> UTCTime -> ByteString
forall a b. (a -> b) -> a -> b
$ SignatureData -> UTCTime
signatureTime SignatureData
sd

        bodyLBS :: ByteString
bodyLBS = a -> ByteString
forall a. ToJSON a => a -> ByteString
A.encode a
body
        bodyHash :: ByteString
bodyHash = ByteString -> ByteString
Base16.encode (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Digest SHA256 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
ByteArray.convert (ByteString -> Digest SHA256
forall a. HashAlgorithm a => ByteString -> Digest a
CH.hashlazy ByteString
bodyLBS :: CH.Digest CH.SHA256)

        -- for some reason AWS doesn't want the x-amz-security-token in the canonical request
        amzHeaders :: RequestHeaders
amzHeaders = [ (CI ByteString
"x-amz-date", ByteString
sigTime)
                     , (CI ByteString
"x-amz-target", ByteString
dyApiVersion ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
Sem.<> ByteString
target)
                     ]

        canonicalHeaders :: RequestHeaders
canonicalHeaders = ((CI ByteString, ByteString)
 -> (CI ByteString, ByteString) -> Ordering)
-> RequestHeaders -> RequestHeaders
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (CI ByteString -> CI ByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (CI ByteString -> CI ByteString -> Ordering)
-> ((CI ByteString, ByteString) -> CI ByteString)
-> (CI ByteString, ByteString)
-> (CI ByteString, ByteString)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (CI ByteString, ByteString) -> CI ByteString
forall a b. (a, b) -> a
fst) (RequestHeaders -> RequestHeaders)
-> RequestHeaders -> RequestHeaders
forall a b. (a -> b) -> a -> b
$ RequestHeaders
amzHeaders RequestHeaders -> RequestHeaders -> RequestHeaders
forall a. [a] -> [a] -> [a]
++
                           [(CI ByteString
"host", ByteString
host),
                            (CI ByteString
"content-type", ByteString
"application/x-amz-json-1.0")]

        canonicalRequest :: ByteString
canonicalRequest = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> [[ByteString]] -> [ByteString]
forall a. [a] -> [[a]] -> [a]
intercalate [ByteString
"\n"] (
                                    [ [ByteString
"POST"]
                                    , [ByteString
"/"]
                                    , [] -- query string
                                    ] [[ByteString]] -> [[ByteString]] -> [[ByteString]]
forall a. [a] -> [a] -> [a]
++
                                    ((CI ByteString, ByteString) -> [ByteString])
-> RequestHeaders -> [[ByteString]]
forall a b. (a -> b) -> [a] -> [b]
map (\(CI ByteString
a,ByteString
b) -> [CI ByteString -> ByteString
forall s. CI s -> s
CI.foldedCase CI ByteString
a,ByteString
":",ByteString
b]) RequestHeaders
canonicalHeaders [[ByteString]] -> [[ByteString]] -> [[ByteString]]
forall a. [a] -> [a] -> [a]
++
                                    [ [] -- end headers
                                    , ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
intersperse ByteString
";" (((CI ByteString, ByteString) -> ByteString)
-> RequestHeaders -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (CI ByteString -> ByteString
forall s. CI s -> s
CI.foldedCase (CI ByteString -> ByteString)
-> ((CI ByteString, ByteString) -> CI ByteString)
-> (CI ByteString, ByteString)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CI ByteString, ByteString) -> CI ByteString
forall a b. (a, b) -> a
fst) RequestHeaders
canonicalHeaders)
                                    , [ByteString
bodyHash]
                                    ])

        auth :: IO ByteString
auth = SignatureData
-> AuthorizationHash
-> ByteString
-> ByteString
-> ByteString
-> ByteString
-> IO ByteString
authorizationV4 SignatureData
sd AuthorizationHash
HmacSHA256 ByteString
rName ByteString
"dynamodb"
                               ByteString
"content-type;host;x-amz-date;x-amz-target"
                               ByteString
canonicalRequest

data AmazonError = AmazonError {
      AmazonError -> Text
aeType    :: T.Text
    , AmazonError -> Maybe Text
aeMessage :: Maybe T.Text
    }

instance FromJSON AmazonError where
    parseJSON :: Value -> Parser AmazonError
parseJSON (Object Object
v) = Text -> Maybe Text -> AmazonError
AmazonError
        (Text -> Maybe Text -> AmazonError)
-> Parser Text -> Parser (Maybe Text -> AmazonError)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"__type"
        Parser (Maybe Text -> AmazonError)
-> Parser (Maybe Text) -> Parser AmazonError
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Parser Text -> Parser (Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message" Parser Text -> Parser Text -> Parser Text
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"Message") Parser (Maybe Text) -> Parser (Maybe Text) -> Parser (Maybe Text)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text -> Parser (Maybe Text)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing)
    parseJSON Value
_ = String -> Parser AmazonError
forall a. HasCallStack => String -> a
error (String -> Parser AmazonError) -> String -> Parser AmazonError
forall a b. (a -> b) -> a -> b
$ String
"aws: unexpected AmazonError message"




-------------------------------------------------------------------------------
ddbResponseConsumer :: A.FromJSON a => IORef DdbResponse -> HTTPResponseConsumer a
ddbResponseConsumer :: forall a. FromJSON a => IORef DdbResponse -> HTTPResponseConsumer a
ddbResponseConsumer IORef DdbResponse
ref Response (ConduitM () ByteString (ResourceT IO) ())
resp = do
    Value
val <- ConduitT () Void (ResourceT IO) Value -> ResourceT IO Value
forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ConduitT () Void (ResourceT IO) Value -> ResourceT IO Value)
-> ConduitT () Void (ResourceT IO) Value -> ResourceT IO Value
forall a b. (a -> b) -> a -> b
$ Response (ConduitM () ByteString (ResourceT IO) ())
-> ConduitM () ByteString (ResourceT IO) ()
forall body. Response body -> body
HTTP.responseBody Response (ConduitM () ByteString (ResourceT IO) ())
resp ConduitM () ByteString (ResourceT IO) ()
-> ConduitT ByteString Void (ResourceT IO) Value
-> ConduitT () Void (ResourceT IO) Value
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| Parser ByteString Value
-> ConduitT ByteString Void (ResourceT IO) Value
forall a (m :: * -> *) b o.
(AttoparsecInput a, MonadThrow m) =>
Parser a b -> ConduitT a o m b
sinkParser (Parser ByteString Value
A.json' Parser ByteString Value
-> Parser ByteString () -> Parser ByteString Value
forall a b.
Parser ByteString a -> Parser ByteString b -> Parser ByteString a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
forall t. Chunk t => Parser t ()
AttoB.endOfInput)
    case Int
statusCode of
      Int
200 -> Value -> ResourceT IO a
rSuccess Value
val
      Int
_   -> Value -> ResourceT IO a
rError Value
val
  where

    header :: CI ByteString -> Maybe Text
header = (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
T.decodeUtf8 (Maybe ByteString -> Maybe Text)
-> (CI ByteString -> Maybe ByteString)
-> CI ByteString
-> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CI ByteString -> RequestHeaders -> Maybe ByteString)
-> RequestHeaders -> CI ByteString -> Maybe ByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip CI ByteString -> RequestHeaders -> Maybe ByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (Response (ConduitM () ByteString (ResourceT IO) ())
-> RequestHeaders
forall body. Response body -> RequestHeaders
HTTP.responseHeaders Response (ConduitM () ByteString (ResourceT IO) ())
resp)
    amzId :: Maybe Text
amzId = CI ByteString -> Maybe Text
header CI ByteString
"x-amzn-RequestId"
    amzCrc :: Maybe Text
amzCrc = CI ByteString -> Maybe Text
header CI ByteString
"x-amz-crc32"
    meta :: DdbResponse
meta = Maybe Text -> Maybe Text -> DdbResponse
DdbResponse Maybe Text
amzCrc Maybe Text
amzId
    tellMeta :: ResourceT IO ()
tellMeta = IO () -> ResourceT IO ()
forall a. IO a -> ResourceT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ResourceT IO ()) -> IO () -> ResourceT IO ()
forall a b. (a -> b) -> a -> b
$ IORef DdbResponse -> DdbResponse -> IO ()
forall m. Monoid m => IORef m -> m -> IO ()
tellMetadataRef IORef DdbResponse
ref DdbResponse
meta

    rSuccess :: Value -> ResourceT IO a
rSuccess Value
val =
      case Value -> Result a
forall a. FromJSON a => Value -> Result a
A.fromJSON Value
val of
        A.Success a
a -> a -> ResourceT IO a
forall a. a -> ResourceT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
        A.Error String
err -> do
            ResourceT IO ()
tellMeta
            DdbLibraryError -> ResourceT IO a
forall e a. (HasCallStack, Exception e) => e -> ResourceT IO a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (DdbLibraryError -> ResourceT IO a)
-> DdbLibraryError -> ResourceT IO a
forall a b. (a -> b) -> a -> b
$ Value -> Text -> DdbLibraryError
JsonProtocolError Value
val (String -> Text
T.pack String
err)

    rError :: Value -> ResourceT IO a
rError Value
val = do
      ResourceT IO ()
tellMeta
      case (Value -> Parser AmazonError) -> Value -> Either String AmazonError
forall a b. (a -> Parser b) -> a -> Either String b
parseEither Value -> Parser AmazonError
forall a. FromJSON a => Value -> Parser a
parseJSON Value
val of
        Left String
e ->
          DdbLibraryError -> ResourceT IO a
forall e a. (HasCallStack, Exception e) => e -> ResourceT IO a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (DdbLibraryError -> ResourceT IO a)
-> DdbLibraryError -> ResourceT IO a
forall a b. (a -> b) -> a -> b
$ Value -> Text -> DdbLibraryError
JsonProtocolError Value
val (String -> Text
T.pack String
e)

        Right AmazonError
err'' -> do
          let e :: Text
e = Int -> Text -> Text
T.drop Int
1 (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> b
snd ((Text, Text) -> Text) -> (Text -> (Text, Text)) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> (Text, Text)
Text -> Text -> (Text, Text)
T.breakOn Text
"#" (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ AmazonError -> Text
aeType AmazonError
err''
          DdbErrCode
errCode <- Text -> ResourceT IO DdbErrCode
forall {a} {m :: * -> *}. (Read a, MonadThrow m) => Text -> m a
readErrCode Text
e
          DdbError -> ResourceT IO a
forall e a. (HasCallStack, Exception e) => e -> ResourceT IO a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (DdbError -> ResourceT IO a) -> DdbError -> ResourceT IO a
forall a b. (a -> b) -> a -> b
$ Int -> DdbErrCode -> Text -> DdbError
DdbError Int
statusCode DdbErrCode
errCode (Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ AmazonError -> Maybe Text
aeMessage AmazonError
err'')

    readErrCode :: Text -> m a
readErrCode Text
txt =
        let txt' :: String
txt' = Text -> String
T.unpack Text
txt
        in case String -> Maybe a
forall a. Read a => String -> Maybe a
readMay String
txt' of
             Just a
e -> a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> m a) -> a -> m a
forall a b. (a -> b) -> a -> b
$ a
e
             Maybe a
Nothing -> DdbLibraryError -> m a
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (Text -> DdbLibraryError
UnknownDynamoErrCode Text
txt)

    HTTP.Status{Int
ByteString
statusCode :: Int
statusMessage :: ByteString
statusCode :: Status -> Int
statusMessage :: Status -> ByteString
..} = Response (ConduitM () ByteString (ResourceT IO) ()) -> Status
forall body. Response body -> Status
HTTP.responseStatus Response (ConduitM () ByteString (ResourceT IO) ())
resp


-- | Conditions used by mutation operations ('PutItem', 'UpdateItem',
-- etc.). The default 'def' instance is empty (no condition).
data Conditions = Conditions CondMerge [Condition]
    deriving (Conditions -> Conditions -> Bool
(Conditions -> Conditions -> Bool)
-> (Conditions -> Conditions -> Bool) -> Eq Conditions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Conditions -> Conditions -> Bool
== :: Conditions -> Conditions -> Bool
$c/= :: Conditions -> Conditions -> Bool
/= :: Conditions -> Conditions -> Bool
Eq,Int -> Conditions -> ShowS
[Conditions] -> ShowS
Conditions -> String
(Int -> Conditions -> ShowS)
-> (Conditions -> String)
-> ([Conditions] -> ShowS)
-> Show Conditions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Conditions -> ShowS
showsPrec :: Int -> Conditions -> ShowS
$cshow :: Conditions -> String
show :: Conditions -> String
$cshowList :: [Conditions] -> ShowS
showList :: [Conditions] -> ShowS
Show,ReadPrec [Conditions]
ReadPrec Conditions
Int -> ReadS Conditions
ReadS [Conditions]
(Int -> ReadS Conditions)
-> ReadS [Conditions]
-> ReadPrec Conditions
-> ReadPrec [Conditions]
-> Read Conditions
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Conditions
readsPrec :: Int -> ReadS Conditions
$creadList :: ReadS [Conditions]
readList :: ReadS [Conditions]
$creadPrec :: ReadPrec Conditions
readPrec :: ReadPrec Conditions
$creadListPrec :: ReadPrec [Conditions]
readListPrec :: ReadPrec [Conditions]
Read,Eq Conditions
Eq Conditions =>
(Conditions -> Conditions -> Ordering)
-> (Conditions -> Conditions -> Bool)
-> (Conditions -> Conditions -> Bool)
-> (Conditions -> Conditions -> Bool)
-> (Conditions -> Conditions -> Bool)
-> (Conditions -> Conditions -> Conditions)
-> (Conditions -> Conditions -> Conditions)
-> Ord Conditions
Conditions -> Conditions -> Bool
Conditions -> Conditions -> Ordering
Conditions -> Conditions -> Conditions
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
$ccompare :: Conditions -> Conditions -> Ordering
compare :: Conditions -> Conditions -> Ordering
$c< :: Conditions -> Conditions -> Bool
< :: Conditions -> Conditions -> Bool
$c<= :: Conditions -> Conditions -> Bool
<= :: Conditions -> Conditions -> Bool
$c> :: Conditions -> Conditions -> Bool
> :: Conditions -> Conditions -> Bool
$c>= :: Conditions -> Conditions -> Bool
>= :: Conditions -> Conditions -> Bool
$cmax :: Conditions -> Conditions -> Conditions
max :: Conditions -> Conditions -> Conditions
$cmin :: Conditions -> Conditions -> Conditions
min :: Conditions -> Conditions -> Conditions
Ord,Typeable)

instance Default Conditions where
    def :: Conditions
def = CondMerge -> [Condition] -> Conditions
Conditions CondMerge
CondAnd []



expectsJson :: Conditions -> [A.Pair]
expectsJson :: Conditions -> [Pair]
expectsJson = Text -> Conditions -> [Pair]
conditionsJson Text
"Expected"


-- | JSON encoding of conditions parameter in various contexts.
conditionsJson :: T.Text -> Conditions -> [A.Pair]
conditionsJson :: Text -> Conditions -> [Pair]
conditionsJson Text
key (Conditions CondMerge
op [Condition]
es) = [Pair]
b [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [Pair]
a
    where
      a :: [Pair]
a = if [Condition] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Condition]
es
          then []
          else [Text -> Key
AK.fromText Text
key Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Pair] -> Value
object ((Condition -> Pair) -> [Condition] -> [Pair]
forall a b. (a -> b) -> [a] -> [b]
map Condition -> Pair
conditionJson [Condition]
es)]

      b :: [Pair]
b = if [Condition] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Int -> [Condition] -> [Condition]
forall a. Int -> [a] -> [a]
take Int
2 [Condition]
es) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1
          then [Key
"ConditionalOperator" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String (CondMerge -> Text
rendCondOp CondMerge
op) ]
          else []


-------------------------------------------------------------------------------
rendCondOp :: CondMerge -> T.Text
rendCondOp :: CondMerge -> Text
rendCondOp CondMerge
CondAnd = Text
"AND"
rendCondOp CondMerge
CondOr = Text
"OR"


-------------------------------------------------------------------------------
-- | How to merge multiple conditions.
data CondMerge = CondAnd | CondOr
    deriving (CondMerge -> CondMerge -> Bool
(CondMerge -> CondMerge -> Bool)
-> (CondMerge -> CondMerge -> Bool) -> Eq CondMerge
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CondMerge -> CondMerge -> Bool
== :: CondMerge -> CondMerge -> Bool
$c/= :: CondMerge -> CondMerge -> Bool
/= :: CondMerge -> CondMerge -> Bool
Eq,Int -> CondMerge -> ShowS
[CondMerge] -> ShowS
CondMerge -> String
(Int -> CondMerge -> ShowS)
-> (CondMerge -> String)
-> ([CondMerge] -> ShowS)
-> Show CondMerge
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CondMerge -> ShowS
showsPrec :: Int -> CondMerge -> ShowS
$cshow :: CondMerge -> String
show :: CondMerge -> String
$cshowList :: [CondMerge] -> ShowS
showList :: [CondMerge] -> ShowS
Show,ReadPrec [CondMerge]
ReadPrec CondMerge
Int -> ReadS CondMerge
ReadS [CondMerge]
(Int -> ReadS CondMerge)
-> ReadS [CondMerge]
-> ReadPrec CondMerge
-> ReadPrec [CondMerge]
-> Read CondMerge
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CondMerge
readsPrec :: Int -> ReadS CondMerge
$creadList :: ReadS [CondMerge]
readList :: ReadS [CondMerge]
$creadPrec :: ReadPrec CondMerge
readPrec :: ReadPrec CondMerge
$creadListPrec :: ReadPrec [CondMerge]
readListPrec :: ReadPrec [CondMerge]
Read,Eq CondMerge
Eq CondMerge =>
(CondMerge -> CondMerge -> Ordering)
-> (CondMerge -> CondMerge -> Bool)
-> (CondMerge -> CondMerge -> Bool)
-> (CondMerge -> CondMerge -> Bool)
-> (CondMerge -> CondMerge -> Bool)
-> (CondMerge -> CondMerge -> CondMerge)
-> (CondMerge -> CondMerge -> CondMerge)
-> Ord CondMerge
CondMerge -> CondMerge -> Bool
CondMerge -> CondMerge -> Ordering
CondMerge -> CondMerge -> CondMerge
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
$ccompare :: CondMerge -> CondMerge -> Ordering
compare :: CondMerge -> CondMerge -> Ordering
$c< :: CondMerge -> CondMerge -> Bool
< :: CondMerge -> CondMerge -> Bool
$c<= :: CondMerge -> CondMerge -> Bool
<= :: CondMerge -> CondMerge -> Bool
$c> :: CondMerge -> CondMerge -> Bool
> :: CondMerge -> CondMerge -> Bool
$c>= :: CondMerge -> CondMerge -> Bool
>= :: CondMerge -> CondMerge -> Bool
$cmax :: CondMerge -> CondMerge -> CondMerge
max :: CondMerge -> CondMerge -> CondMerge
$cmin :: CondMerge -> CondMerge -> CondMerge
min :: CondMerge -> CondMerge -> CondMerge
Ord,Typeable)


-- | A condition used by mutation operations ('PutItem', 'UpdateItem', etc.).
data Condition = Condition {
      Condition -> Text
condAttr :: T.Text
    -- ^ Attribute to use as the basis for this conditional
    , Condition -> CondOp
condOp   :: CondOp
    -- ^ Operation on the selected attribute
    } deriving (Condition -> Condition -> Bool
(Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool) -> Eq Condition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Condition -> Condition -> Bool
== :: Condition -> Condition -> Bool
$c/= :: Condition -> Condition -> Bool
/= :: Condition -> Condition -> Bool
Eq,Int -> Condition -> ShowS
[Condition] -> ShowS
Condition -> String
(Int -> Condition -> ShowS)
-> (Condition -> String)
-> ([Condition] -> ShowS)
-> Show Condition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Condition -> ShowS
showsPrec :: Int -> Condition -> ShowS
$cshow :: Condition -> String
show :: Condition -> String
$cshowList :: [Condition] -> ShowS
showList :: [Condition] -> ShowS
Show,ReadPrec [Condition]
ReadPrec Condition
Int -> ReadS Condition
ReadS [Condition]
(Int -> ReadS Condition)
-> ReadS [Condition]
-> ReadPrec Condition
-> ReadPrec [Condition]
-> Read Condition
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Condition
readsPrec :: Int -> ReadS Condition
$creadList :: ReadS [Condition]
readList :: ReadS [Condition]
$creadPrec :: ReadPrec Condition
readPrec :: ReadPrec Condition
$creadListPrec :: ReadPrec [Condition]
readListPrec :: ReadPrec [Condition]
Read,Eq Condition
Eq Condition =>
(Condition -> Condition -> Ordering)
-> (Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool)
-> (Condition -> Condition -> Condition)
-> (Condition -> Condition -> Condition)
-> Ord Condition
Condition -> Condition -> Bool
Condition -> Condition -> Ordering
Condition -> Condition -> Condition
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
$ccompare :: Condition -> Condition -> Ordering
compare :: Condition -> Condition -> Ordering
$c< :: Condition -> Condition -> Bool
< :: Condition -> Condition -> Bool
$c<= :: Condition -> Condition -> Bool
<= :: Condition -> Condition -> Bool
$c> :: Condition -> Condition -> Bool
> :: Condition -> Condition -> Bool
$c>= :: Condition -> Condition -> Bool
>= :: Condition -> Condition -> Bool
$cmax :: Condition -> Condition -> Condition
max :: Condition -> Condition -> Condition
$cmin :: Condition -> Condition -> Condition
min :: Condition -> Condition -> Condition
Ord,Typeable)


-------------------------------------------------------------------------------
-- | Conditional operation to perform on a field.
data CondOp
    = DEq DValue
    | NotEq DValue
    | DLE DValue
    | DLT DValue
    | DGE DValue
    | DGT DValue
    | NotNull
    | IsNull
    | Contains DValue
    | NotContains DValue
    | Begins DValue
    | In [DValue]
    | Between DValue DValue
    deriving (CondOp -> CondOp -> Bool
(CondOp -> CondOp -> Bool)
-> (CondOp -> CondOp -> Bool) -> Eq CondOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CondOp -> CondOp -> Bool
== :: CondOp -> CondOp -> Bool
$c/= :: CondOp -> CondOp -> Bool
/= :: CondOp -> CondOp -> Bool
Eq,Int -> CondOp -> ShowS
[CondOp] -> ShowS
CondOp -> String
(Int -> CondOp -> ShowS)
-> (CondOp -> String) -> ([CondOp] -> ShowS) -> Show CondOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CondOp -> ShowS
showsPrec :: Int -> CondOp -> ShowS
$cshow :: CondOp -> String
show :: CondOp -> String
$cshowList :: [CondOp] -> ShowS
showList :: [CondOp] -> ShowS
Show,ReadPrec [CondOp]
ReadPrec CondOp
Int -> ReadS CondOp
ReadS [CondOp]
(Int -> ReadS CondOp)
-> ReadS [CondOp]
-> ReadPrec CondOp
-> ReadPrec [CondOp]
-> Read CondOp
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CondOp
readsPrec :: Int -> ReadS CondOp
$creadList :: ReadS [CondOp]
readList :: ReadS [CondOp]
$creadPrec :: ReadPrec CondOp
readPrec :: ReadPrec CondOp
$creadListPrec :: ReadPrec [CondOp]
readListPrec :: ReadPrec [CondOp]
Read,Eq CondOp
Eq CondOp =>
(CondOp -> CondOp -> Ordering)
-> (CondOp -> CondOp -> Bool)
-> (CondOp -> CondOp -> Bool)
-> (CondOp -> CondOp -> Bool)
-> (CondOp -> CondOp -> Bool)
-> (CondOp -> CondOp -> CondOp)
-> (CondOp -> CondOp -> CondOp)
-> Ord CondOp
CondOp -> CondOp -> Bool
CondOp -> CondOp -> Ordering
CondOp -> CondOp -> CondOp
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
$ccompare :: CondOp -> CondOp -> Ordering
compare :: CondOp -> CondOp -> Ordering
$c< :: CondOp -> CondOp -> Bool
< :: CondOp -> CondOp -> Bool
$c<= :: CondOp -> CondOp -> Bool
<= :: CondOp -> CondOp -> Bool
$c> :: CondOp -> CondOp -> Bool
> :: CondOp -> CondOp -> Bool
$c>= :: CondOp -> CondOp -> Bool
>= :: CondOp -> CondOp -> Bool
$cmax :: CondOp -> CondOp -> CondOp
max :: CondOp -> CondOp -> CondOp
$cmin :: CondOp -> CondOp -> CondOp
min :: CondOp -> CondOp -> CondOp
Ord,Typeable)


-------------------------------------------------------------------------------
getCondValues :: CondOp -> [DValue]
getCondValues :: CondOp -> [DValue]
getCondValues CondOp
c = case CondOp
c of
    DEq DValue
v -> [DValue
v]
    NotEq DValue
v -> [DValue
v]
    DLE DValue
v -> [DValue
v]
    DLT DValue
v -> [DValue
v]
    DGE DValue
v -> [DValue
v]
    DGT DValue
v -> [DValue
v]
    CondOp
NotNull -> []
    CondOp
IsNull -> []
    Contains DValue
v -> [DValue
v]
    NotContains DValue
v -> [DValue
v]
    Begins DValue
v -> [DValue
v]
    In [DValue]
v -> [DValue]
v
    Between DValue
a DValue
b -> [DValue
a,DValue
b]


-------------------------------------------------------------------------------
renderCondOp :: CondOp -> T.Text
renderCondOp :: CondOp -> Text
renderCondOp CondOp
c = case CondOp
c of
    DEq{} -> Text
"EQ"
    NotEq{} -> Text
"NE"
    DLE{} -> Text
"LE"
    DLT{} -> Text
"LT"
    DGE{} -> Text
"GE"
    DGT{} -> Text
"GT"
    CondOp
NotNull -> Text
"NOT_NULL"
    CondOp
IsNull -> Text
"NULL"
    Contains{} -> Text
"CONTAINS"
    NotContains{} -> Text
"NOT_CONTAINS"
    Begins{} -> Text
"BEGINS_WITH"
    In{} -> Text
"IN"
    Between{} -> Text
"BETWEEN"


conditionJson :: Condition -> Pair
conditionJson :: Condition -> Pair
conditionJson Condition{Text
CondOp
condAttr :: Condition -> Text
condOp :: Condition -> CondOp
condAttr :: Text
condOp :: CondOp
..} = Text -> Key
AK.fromText Text
condAttr Key -> CondOp -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= CondOp
condOp


instance ToJSON CondOp where
    toJSON :: CondOp -> Value
toJSON CondOp
c = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ (Key
"ComparisonOperator" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String (CondOp -> Text
renderCondOp CondOp
c)) Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
: [Pair]
valueList
      where
        valueList :: [Pair]
valueList =
          let vs :: [DValue]
vs = CondOp -> [DValue]
getCondValues CondOp
c in
            if [DValue] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [DValue]
vs
            then []
            else [Key
"AttributeValueList" Key -> [DValue] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [DValue]
vs]

-------------------------------------------------------------------------------
dyApiVersion :: B.ByteString
dyApiVersion :: ByteString
dyApiVersion = ByteString
"DynamoDB_20120810."



-------------------------------------------------------------------------------
-- | The standard response metrics on capacity consumption.
data ConsumedCapacity = ConsumedCapacity {
      ConsumedCapacity -> Int64
capacityUnits       :: Int64
    , ConsumedCapacity -> [(Text, Int64)]
capacityGlobalIndex :: [(T.Text, Int64)]
    , ConsumedCapacity -> [(Text, Int64)]
capacityLocalIndex  :: [(T.Text, Int64)]
    , ConsumedCapacity -> Maybe Int64
capacityTableUnits  :: Maybe Int64
    , ConsumedCapacity -> Text
capacityTable       :: T.Text
    } deriving (ConsumedCapacity -> ConsumedCapacity -> Bool
(ConsumedCapacity -> ConsumedCapacity -> Bool)
-> (ConsumedCapacity -> ConsumedCapacity -> Bool)
-> Eq ConsumedCapacity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ConsumedCapacity -> ConsumedCapacity -> Bool
== :: ConsumedCapacity -> ConsumedCapacity -> Bool
$c/= :: ConsumedCapacity -> ConsumedCapacity -> Bool
/= :: ConsumedCapacity -> ConsumedCapacity -> Bool
Eq,Int -> ConsumedCapacity -> ShowS
[ConsumedCapacity] -> ShowS
ConsumedCapacity -> String
(Int -> ConsumedCapacity -> ShowS)
-> (ConsumedCapacity -> String)
-> ([ConsumedCapacity] -> ShowS)
-> Show ConsumedCapacity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ConsumedCapacity -> ShowS
showsPrec :: Int -> ConsumedCapacity -> ShowS
$cshow :: ConsumedCapacity -> String
show :: ConsumedCapacity -> String
$cshowList :: [ConsumedCapacity] -> ShowS
showList :: [ConsumedCapacity] -> ShowS
Show,ReadPrec [ConsumedCapacity]
ReadPrec ConsumedCapacity
Int -> ReadS ConsumedCapacity
ReadS [ConsumedCapacity]
(Int -> ReadS ConsumedCapacity)
-> ReadS [ConsumedCapacity]
-> ReadPrec ConsumedCapacity
-> ReadPrec [ConsumedCapacity]
-> Read ConsumedCapacity
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ConsumedCapacity
readsPrec :: Int -> ReadS ConsumedCapacity
$creadList :: ReadS [ConsumedCapacity]
readList :: ReadS [ConsumedCapacity]
$creadPrec :: ReadPrec ConsumedCapacity
readPrec :: ReadPrec ConsumedCapacity
$creadListPrec :: ReadPrec [ConsumedCapacity]
readListPrec :: ReadPrec [ConsumedCapacity]
Read,Eq ConsumedCapacity
Eq ConsumedCapacity =>
(ConsumedCapacity -> ConsumedCapacity -> Ordering)
-> (ConsumedCapacity -> ConsumedCapacity -> Bool)
-> (ConsumedCapacity -> ConsumedCapacity -> Bool)
-> (ConsumedCapacity -> ConsumedCapacity -> Bool)
-> (ConsumedCapacity -> ConsumedCapacity -> Bool)
-> (ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity)
-> (ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity)
-> Ord ConsumedCapacity
ConsumedCapacity -> ConsumedCapacity -> Bool
ConsumedCapacity -> ConsumedCapacity -> Ordering
ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity
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
$ccompare :: ConsumedCapacity -> ConsumedCapacity -> Ordering
compare :: ConsumedCapacity -> ConsumedCapacity -> Ordering
$c< :: ConsumedCapacity -> ConsumedCapacity -> Bool
< :: ConsumedCapacity -> ConsumedCapacity -> Bool
$c<= :: ConsumedCapacity -> ConsumedCapacity -> Bool
<= :: ConsumedCapacity -> ConsumedCapacity -> Bool
$c> :: ConsumedCapacity -> ConsumedCapacity -> Bool
> :: ConsumedCapacity -> ConsumedCapacity -> Bool
$c>= :: ConsumedCapacity -> ConsumedCapacity -> Bool
>= :: ConsumedCapacity -> ConsumedCapacity -> Bool
$cmax :: ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity
max :: ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity
$cmin :: ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity
min :: ConsumedCapacity -> ConsumedCapacity -> ConsumedCapacity
Ord,Typeable)


instance FromJSON ConsumedCapacity where
    parseJSON :: Value -> Parser ConsumedCapacity
parseJSON (Object Object
o) = Int64
-> [(Text, Int64)]
-> [(Text, Int64)]
-> Maybe Int64
-> Text
-> ConsumedCapacity
ConsumedCapacity
      (Int64
 -> [(Text, Int64)]
 -> [(Text, Int64)]
 -> Maybe Int64
 -> Text
 -> ConsumedCapacity)
-> Parser Int64
-> Parser
     ([(Text, Int64)]
      -> [(Text, Int64)] -> Maybe Int64 -> Text -> ConsumedCapacity)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Int64
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"CapacityUnits"
      Parser
  ([(Text, Int64)]
   -> [(Text, Int64)] -> Maybe Int64 -> Text -> ConsumedCapacity)
-> Parser [(Text, Int64)]
-> Parser
     ([(Text, Int64)] -> Maybe Int64 -> Text -> ConsumedCapacity)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (((Key, Int64) -> (Text, Int64))
-> [(Key, Int64)] -> [(Text, Int64)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Key
k, Int64
v) -> (Key -> Text
AK.toText Key
k, Int64
v)) ([(Key, Int64)] -> [(Text, Int64)])
-> (KeyMap Int64 -> [(Key, Int64)])
-> KeyMap Int64
-> [(Text, Int64)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyMap Int64 -> [(Key, Int64)]
forall v. KeyMap v -> [(Key, v)]
KM.toList (KeyMap Int64 -> [(Text, Int64)])
-> Parser (KeyMap Int64) -> Parser [(Text, Int64)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser (Maybe (KeyMap Int64))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"GlobalSecondaryIndexes" Parser (Maybe (KeyMap Int64))
-> KeyMap Int64 -> Parser (KeyMap Int64)
forall a. Parser (Maybe a) -> a -> Parser a
.!= KeyMap Int64
forall a. Monoid a => a
mempty)
      Parser ([(Text, Int64)] -> Maybe Int64 -> Text -> ConsumedCapacity)
-> Parser [(Text, Int64)]
-> Parser (Maybe Int64 -> Text -> ConsumedCapacity)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (((Key, Int64) -> (Text, Int64))
-> [(Key, Int64)] -> [(Text, Int64)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Key
k, Int64
v) -> (Key -> Text
AK.toText Key
k, Int64
v)) ([(Key, Int64)] -> [(Text, Int64)])
-> (KeyMap Int64 -> [(Key, Int64)])
-> KeyMap Int64
-> [(Text, Int64)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyMap Int64 -> [(Key, Int64)]
forall v. KeyMap v -> [(Key, v)]
KM.toList (KeyMap Int64 -> [(Text, Int64)])
-> Parser (KeyMap Int64) -> Parser [(Text, Int64)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser (Maybe (KeyMap Int64))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"LocalSecondaryIndexes" Parser (Maybe (KeyMap Int64))
-> KeyMap Int64 -> Parser (KeyMap Int64)
forall a. Parser (Maybe a) -> a -> Parser a
.!= KeyMap Int64
forall a. Monoid a => a
mempty)
      Parser (Maybe Int64 -> Text -> ConsumedCapacity)
-> Parser (Maybe Int64) -> Parser (Text -> ConsumedCapacity)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Object
o Object -> Key -> Parser (Maybe Object)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"Table" Parser (Maybe Object)
-> (Maybe Object -> Parser (Maybe Int64)) -> Parser (Maybe Int64)
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Parser (Maybe Int64)
-> (Object -> Parser (Maybe Int64))
-> Maybe Object
-> Parser (Maybe Int64)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe Int64 -> Parser (Maybe Int64)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int64
forall a. Maybe a
Nothing) (Object -> Key -> Parser (Maybe Int64)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"CapacityUnits"))
      Parser (Text -> ConsumedCapacity)
-> Parser Text -> Parser ConsumedCapacity
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"TableName"
    parseJSON Value
_ = String -> Parser ConsumedCapacity
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ConsumedCapacity must be an Object."



data ReturnConsumption = RCIndexes | RCTotal | RCNone
    deriving (ReturnConsumption -> ReturnConsumption -> Bool
(ReturnConsumption -> ReturnConsumption -> Bool)
-> (ReturnConsumption -> ReturnConsumption -> Bool)
-> Eq ReturnConsumption
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReturnConsumption -> ReturnConsumption -> Bool
== :: ReturnConsumption -> ReturnConsumption -> Bool
$c/= :: ReturnConsumption -> ReturnConsumption -> Bool
/= :: ReturnConsumption -> ReturnConsumption -> Bool
Eq,Int -> ReturnConsumption -> ShowS
[ReturnConsumption] -> ShowS
ReturnConsumption -> String
(Int -> ReturnConsumption -> ShowS)
-> (ReturnConsumption -> String)
-> ([ReturnConsumption] -> ShowS)
-> Show ReturnConsumption
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReturnConsumption -> ShowS
showsPrec :: Int -> ReturnConsumption -> ShowS
$cshow :: ReturnConsumption -> String
show :: ReturnConsumption -> String
$cshowList :: [ReturnConsumption] -> ShowS
showList :: [ReturnConsumption] -> ShowS
Show,ReadPrec [ReturnConsumption]
ReadPrec ReturnConsumption
Int -> ReadS ReturnConsumption
ReadS [ReturnConsumption]
(Int -> ReadS ReturnConsumption)
-> ReadS [ReturnConsumption]
-> ReadPrec ReturnConsumption
-> ReadPrec [ReturnConsumption]
-> Read ReturnConsumption
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ReturnConsumption
readsPrec :: Int -> ReadS ReturnConsumption
$creadList :: ReadS [ReturnConsumption]
readList :: ReadS [ReturnConsumption]
$creadPrec :: ReadPrec ReturnConsumption
readPrec :: ReadPrec ReturnConsumption
$creadListPrec :: ReadPrec [ReturnConsumption]
readListPrec :: ReadPrec [ReturnConsumption]
Read,Eq ReturnConsumption
Eq ReturnConsumption =>
(ReturnConsumption -> ReturnConsumption -> Ordering)
-> (ReturnConsumption -> ReturnConsumption -> Bool)
-> (ReturnConsumption -> ReturnConsumption -> Bool)
-> (ReturnConsumption -> ReturnConsumption -> Bool)
-> (ReturnConsumption -> ReturnConsumption -> Bool)
-> (ReturnConsumption -> ReturnConsumption -> ReturnConsumption)
-> (ReturnConsumption -> ReturnConsumption -> ReturnConsumption)
-> Ord ReturnConsumption
ReturnConsumption -> ReturnConsumption -> Bool
ReturnConsumption -> ReturnConsumption -> Ordering
ReturnConsumption -> ReturnConsumption -> ReturnConsumption
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
$ccompare :: ReturnConsumption -> ReturnConsumption -> Ordering
compare :: ReturnConsumption -> ReturnConsumption -> Ordering
$c< :: ReturnConsumption -> ReturnConsumption -> Bool
< :: ReturnConsumption -> ReturnConsumption -> Bool
$c<= :: ReturnConsumption -> ReturnConsumption -> Bool
<= :: ReturnConsumption -> ReturnConsumption -> Bool
$c> :: ReturnConsumption -> ReturnConsumption -> Bool
> :: ReturnConsumption -> ReturnConsumption -> Bool
$c>= :: ReturnConsumption -> ReturnConsumption -> Bool
>= :: ReturnConsumption -> ReturnConsumption -> Bool
$cmax :: ReturnConsumption -> ReturnConsumption -> ReturnConsumption
max :: ReturnConsumption -> ReturnConsumption -> ReturnConsumption
$cmin :: ReturnConsumption -> ReturnConsumption -> ReturnConsumption
min :: ReturnConsumption -> ReturnConsumption -> ReturnConsumption
Ord,Typeable)

instance ToJSON ReturnConsumption where
    toJSON :: ReturnConsumption -> Value
toJSON ReturnConsumption
RCIndexes = Text -> Value
String Text
"INDEXES"
    toJSON ReturnConsumption
RCTotal = Text -> Value
String Text
"TOTAL"
    toJSON ReturnConsumption
RCNone = Text -> Value
String Text
"NONE"

instance Default ReturnConsumption where
    def :: ReturnConsumption
def = ReturnConsumption
RCNone

data ReturnItemCollectionMetrics = RICMSize | RICMNone
    deriving (ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
(ReturnItemCollectionMetrics
 -> ReturnItemCollectionMetrics -> Bool)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> Bool)
-> Eq ReturnItemCollectionMetrics
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
== :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
$c/= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
/= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
Eq,Int -> ReturnItemCollectionMetrics -> ShowS
[ReturnItemCollectionMetrics] -> ShowS
ReturnItemCollectionMetrics -> String
(Int -> ReturnItemCollectionMetrics -> ShowS)
-> (ReturnItemCollectionMetrics -> String)
-> ([ReturnItemCollectionMetrics] -> ShowS)
-> Show ReturnItemCollectionMetrics
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReturnItemCollectionMetrics -> ShowS
showsPrec :: Int -> ReturnItemCollectionMetrics -> ShowS
$cshow :: ReturnItemCollectionMetrics -> String
show :: ReturnItemCollectionMetrics -> String
$cshowList :: [ReturnItemCollectionMetrics] -> ShowS
showList :: [ReturnItemCollectionMetrics] -> ShowS
Show,ReadPrec [ReturnItemCollectionMetrics]
ReadPrec ReturnItemCollectionMetrics
Int -> ReadS ReturnItemCollectionMetrics
ReadS [ReturnItemCollectionMetrics]
(Int -> ReadS ReturnItemCollectionMetrics)
-> ReadS [ReturnItemCollectionMetrics]
-> ReadPrec ReturnItemCollectionMetrics
-> ReadPrec [ReturnItemCollectionMetrics]
-> Read ReturnItemCollectionMetrics
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ReturnItemCollectionMetrics
readsPrec :: Int -> ReadS ReturnItemCollectionMetrics
$creadList :: ReadS [ReturnItemCollectionMetrics]
readList :: ReadS [ReturnItemCollectionMetrics]
$creadPrec :: ReadPrec ReturnItemCollectionMetrics
readPrec :: ReadPrec ReturnItemCollectionMetrics
$creadListPrec :: ReadPrec [ReturnItemCollectionMetrics]
readListPrec :: ReadPrec [ReturnItemCollectionMetrics]
Read,Eq ReturnItemCollectionMetrics
Eq ReturnItemCollectionMetrics =>
(ReturnItemCollectionMetrics
 -> ReturnItemCollectionMetrics -> Ordering)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> Bool)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> Bool)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> Bool)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> Bool)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics)
-> (ReturnItemCollectionMetrics
    -> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics)
-> Ord ReturnItemCollectionMetrics
ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> Ordering
ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics
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
$ccompare :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> Ordering
compare :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> Ordering
$c< :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
< :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
$c<= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
<= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
$c> :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
> :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
$c>= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
>= :: ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics -> Bool
$cmax :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics
max :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics
$cmin :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics
min :: ReturnItemCollectionMetrics
-> ReturnItemCollectionMetrics -> ReturnItemCollectionMetrics
Ord,Typeable)

instance ToJSON ReturnItemCollectionMetrics where
    toJSON :: ReturnItemCollectionMetrics -> Value
toJSON ReturnItemCollectionMetrics
RICMSize = Text -> Value
String Text
"SIZE"
    toJSON ReturnItemCollectionMetrics
RICMNone = Text -> Value
String Text
"NONE"

instance Default ReturnItemCollectionMetrics where
    def :: ReturnItemCollectionMetrics
def = ReturnItemCollectionMetrics
RICMNone


data ItemCollectionMetrics = ItemCollectionMetrics {
      ItemCollectionMetrics -> (Text, DValue)
icmKey      :: (T.Text, DValue)
    , ItemCollectionMetrics -> [Double]
icmEstimate :: [Double]
    } deriving (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
(ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> Eq ItemCollectionMetrics
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
== :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
$c/= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
/= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
Eq,Int -> ItemCollectionMetrics -> ShowS
[ItemCollectionMetrics] -> ShowS
ItemCollectionMetrics -> String
(Int -> ItemCollectionMetrics -> ShowS)
-> (ItemCollectionMetrics -> String)
-> ([ItemCollectionMetrics] -> ShowS)
-> Show ItemCollectionMetrics
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ItemCollectionMetrics -> ShowS
showsPrec :: Int -> ItemCollectionMetrics -> ShowS
$cshow :: ItemCollectionMetrics -> String
show :: ItemCollectionMetrics -> String
$cshowList :: [ItemCollectionMetrics] -> ShowS
showList :: [ItemCollectionMetrics] -> ShowS
Show,ReadPrec [ItemCollectionMetrics]
ReadPrec ItemCollectionMetrics
Int -> ReadS ItemCollectionMetrics
ReadS [ItemCollectionMetrics]
(Int -> ReadS ItemCollectionMetrics)
-> ReadS [ItemCollectionMetrics]
-> ReadPrec ItemCollectionMetrics
-> ReadPrec [ItemCollectionMetrics]
-> Read ItemCollectionMetrics
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ItemCollectionMetrics
readsPrec :: Int -> ReadS ItemCollectionMetrics
$creadList :: ReadS [ItemCollectionMetrics]
readList :: ReadS [ItemCollectionMetrics]
$creadPrec :: ReadPrec ItemCollectionMetrics
readPrec :: ReadPrec ItemCollectionMetrics
$creadListPrec :: ReadPrec [ItemCollectionMetrics]
readListPrec :: ReadPrec [ItemCollectionMetrics]
Read,Eq ItemCollectionMetrics
Eq ItemCollectionMetrics =>
(ItemCollectionMetrics -> ItemCollectionMetrics -> Ordering)
-> (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> (ItemCollectionMetrics -> ItemCollectionMetrics -> Bool)
-> (ItemCollectionMetrics
    -> ItemCollectionMetrics -> ItemCollectionMetrics)
-> (ItemCollectionMetrics
    -> ItemCollectionMetrics -> ItemCollectionMetrics)
-> Ord ItemCollectionMetrics
ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
ItemCollectionMetrics -> ItemCollectionMetrics -> Ordering
ItemCollectionMetrics
-> ItemCollectionMetrics -> ItemCollectionMetrics
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
$ccompare :: ItemCollectionMetrics -> ItemCollectionMetrics -> Ordering
compare :: ItemCollectionMetrics -> ItemCollectionMetrics -> Ordering
$c< :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
< :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
$c<= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
<= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
$c> :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
> :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
$c>= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
>= :: ItemCollectionMetrics -> ItemCollectionMetrics -> Bool
$cmax :: ItemCollectionMetrics
-> ItemCollectionMetrics -> ItemCollectionMetrics
max :: ItemCollectionMetrics
-> ItemCollectionMetrics -> ItemCollectionMetrics
$cmin :: ItemCollectionMetrics
-> ItemCollectionMetrics -> ItemCollectionMetrics
min :: ItemCollectionMetrics
-> ItemCollectionMetrics -> ItemCollectionMetrics
Ord,Typeable)


instance FromJSON ItemCollectionMetrics where
    parseJSON :: Value -> Parser ItemCollectionMetrics
parseJSON (Object Object
o) = (Text, DValue) -> [Double] -> ItemCollectionMetrics
ItemCollectionMetrics
      ((Text, DValue) -> [Double] -> ItemCollectionMetrics)
-> Parser (Text, DValue)
-> Parser ([Double] -> ItemCollectionMetrics)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (do KeyMap DValue
m <- Object
o Object -> Key -> Parser (KeyMap DValue)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"ItemCollectionKey"
              (Text, DValue) -> Parser (Text, DValue)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text, DValue) -> Parser (Text, DValue))
-> (Text, DValue) -> Parser (Text, DValue)
forall a b. (a -> b) -> a -> b
$ (\(Key
k, DValue
v) -> (Key -> Text
AK.toText Key
k, DValue
v)) ((Key, DValue) -> (Text, DValue))
-> (Key, DValue) -> (Text, DValue)
forall a b. (a -> b) -> a -> b
$ [(Key, DValue)] -> (Key, DValue)
forall a. HasCallStack => [a] -> a
head ([(Key, DValue)] -> (Key, DValue))
-> [(Key, DValue)] -> (Key, DValue)
forall a b. (a -> b) -> a -> b
$ KeyMap DValue -> [(Key, DValue)]
forall v. KeyMap v -> [(Key, v)]
KM.toList KeyMap DValue
m)
      Parser ([Double] -> ItemCollectionMetrics)
-> Parser [Double] -> Parser ItemCollectionMetrics
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser [Double]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"SizeEstimateRangeGB"
    parseJSON Value
_ = String -> Parser ItemCollectionMetrics
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"ItemCollectionMetrics must be an Object."


-------------------------------------------------------------------------------
-- | What to return from the current update operation
data UpdateReturn
    = URNone                    -- ^ Return nothing
    | URAllOld                  -- ^ Return old values
    | URUpdatedOld              -- ^ Return old values with a newer replacement
    | URAllNew                  -- ^ Return new values
    | URUpdatedNew              -- ^ Return new values that were replacements
    deriving (UpdateReturn -> UpdateReturn -> Bool
(UpdateReturn -> UpdateReturn -> Bool)
-> (UpdateReturn -> UpdateReturn -> Bool) -> Eq UpdateReturn
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UpdateReturn -> UpdateReturn -> Bool
== :: UpdateReturn -> UpdateReturn -> Bool
$c/= :: UpdateReturn -> UpdateReturn -> Bool
/= :: UpdateReturn -> UpdateReturn -> Bool
Eq,Int -> UpdateReturn -> ShowS
[UpdateReturn] -> ShowS
UpdateReturn -> String
(Int -> UpdateReturn -> ShowS)
-> (UpdateReturn -> String)
-> ([UpdateReturn] -> ShowS)
-> Show UpdateReturn
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> UpdateReturn -> ShowS
showsPrec :: Int -> UpdateReturn -> ShowS
$cshow :: UpdateReturn -> String
show :: UpdateReturn -> String
$cshowList :: [UpdateReturn] -> ShowS
showList :: [UpdateReturn] -> ShowS
Show,ReadPrec [UpdateReturn]
ReadPrec UpdateReturn
Int -> ReadS UpdateReturn
ReadS [UpdateReturn]
(Int -> ReadS UpdateReturn)
-> ReadS [UpdateReturn]
-> ReadPrec UpdateReturn
-> ReadPrec [UpdateReturn]
-> Read UpdateReturn
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS UpdateReturn
readsPrec :: Int -> ReadS UpdateReturn
$creadList :: ReadS [UpdateReturn]
readList :: ReadS [UpdateReturn]
$creadPrec :: ReadPrec UpdateReturn
readPrec :: ReadPrec UpdateReturn
$creadListPrec :: ReadPrec [UpdateReturn]
readListPrec :: ReadPrec [UpdateReturn]
Read,Eq UpdateReturn
Eq UpdateReturn =>
(UpdateReturn -> UpdateReturn -> Ordering)
-> (UpdateReturn -> UpdateReturn -> Bool)
-> (UpdateReturn -> UpdateReturn -> Bool)
-> (UpdateReturn -> UpdateReturn -> Bool)
-> (UpdateReturn -> UpdateReturn -> Bool)
-> (UpdateReturn -> UpdateReturn -> UpdateReturn)
-> (UpdateReturn -> UpdateReturn -> UpdateReturn)
-> Ord UpdateReturn
UpdateReturn -> UpdateReturn -> Bool
UpdateReturn -> UpdateReturn -> Ordering
UpdateReturn -> UpdateReturn -> UpdateReturn
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
$ccompare :: UpdateReturn -> UpdateReturn -> Ordering
compare :: UpdateReturn -> UpdateReturn -> Ordering
$c< :: UpdateReturn -> UpdateReturn -> Bool
< :: UpdateReturn -> UpdateReturn -> Bool
$c<= :: UpdateReturn -> UpdateReturn -> Bool
<= :: UpdateReturn -> UpdateReturn -> Bool
$c> :: UpdateReturn -> UpdateReturn -> Bool
> :: UpdateReturn -> UpdateReturn -> Bool
$c>= :: UpdateReturn -> UpdateReturn -> Bool
>= :: UpdateReturn -> UpdateReturn -> Bool
$cmax :: UpdateReturn -> UpdateReturn -> UpdateReturn
max :: UpdateReturn -> UpdateReturn -> UpdateReturn
$cmin :: UpdateReturn -> UpdateReturn -> UpdateReturn
min :: UpdateReturn -> UpdateReturn -> UpdateReturn
Ord,Typeable)


instance ToJSON UpdateReturn where
    toJSON :: UpdateReturn -> Value
toJSON UpdateReturn
URNone = Value -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value
String Text
"NONE")
    toJSON UpdateReturn
URAllOld = Value -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value
String Text
"ALL_OLD")
    toJSON UpdateReturn
URUpdatedOld = Value -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value
String Text
"UPDATED_OLD")
    toJSON UpdateReturn
URAllNew = Value -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value
String Text
"ALL_NEW")
    toJSON UpdateReturn
URUpdatedNew = Value -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value
String Text
"UPDATED_NEW")


instance Default UpdateReturn where
    def :: UpdateReturn
def = UpdateReturn
URNone



-------------------------------------------------------------------------------
-- | What to return from a 'Query' or 'Scan' query.
data QuerySelect
    = SelectSpecific [T.Text]
    -- ^ Only return selected attributes
    | SelectCount
    -- ^ Return counts instead of attributes
    | SelectProjected
    -- ^ Return index-projected attributes
    | SelectAll
    -- ^ Default. Return everything.
    deriving (QuerySelect -> QuerySelect -> Bool
(QuerySelect -> QuerySelect -> Bool)
-> (QuerySelect -> QuerySelect -> Bool) -> Eq QuerySelect
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: QuerySelect -> QuerySelect -> Bool
== :: QuerySelect -> QuerySelect -> Bool
$c/= :: QuerySelect -> QuerySelect -> Bool
/= :: QuerySelect -> QuerySelect -> Bool
Eq,Int -> QuerySelect -> ShowS
[QuerySelect] -> ShowS
QuerySelect -> String
(Int -> QuerySelect -> ShowS)
-> (QuerySelect -> String)
-> ([QuerySelect] -> ShowS)
-> Show QuerySelect
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> QuerySelect -> ShowS
showsPrec :: Int -> QuerySelect -> ShowS
$cshow :: QuerySelect -> String
show :: QuerySelect -> String
$cshowList :: [QuerySelect] -> ShowS
showList :: [QuerySelect] -> ShowS
Show,ReadPrec [QuerySelect]
ReadPrec QuerySelect
Int -> ReadS QuerySelect
ReadS [QuerySelect]
(Int -> ReadS QuerySelect)
-> ReadS [QuerySelect]
-> ReadPrec QuerySelect
-> ReadPrec [QuerySelect]
-> Read QuerySelect
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS QuerySelect
readsPrec :: Int -> ReadS QuerySelect
$creadList :: ReadS [QuerySelect]
readList :: ReadS [QuerySelect]
$creadPrec :: ReadPrec QuerySelect
readPrec :: ReadPrec QuerySelect
$creadListPrec :: ReadPrec [QuerySelect]
readListPrec :: ReadPrec [QuerySelect]
Read,Eq QuerySelect
Eq QuerySelect =>
(QuerySelect -> QuerySelect -> Ordering)
-> (QuerySelect -> QuerySelect -> Bool)
-> (QuerySelect -> QuerySelect -> Bool)
-> (QuerySelect -> QuerySelect -> Bool)
-> (QuerySelect -> QuerySelect -> Bool)
-> (QuerySelect -> QuerySelect -> QuerySelect)
-> (QuerySelect -> QuerySelect -> QuerySelect)
-> Ord QuerySelect
QuerySelect -> QuerySelect -> Bool
QuerySelect -> QuerySelect -> Ordering
QuerySelect -> QuerySelect -> QuerySelect
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
$ccompare :: QuerySelect -> QuerySelect -> Ordering
compare :: QuerySelect -> QuerySelect -> Ordering
$c< :: QuerySelect -> QuerySelect -> Bool
< :: QuerySelect -> QuerySelect -> Bool
$c<= :: QuerySelect -> QuerySelect -> Bool
<= :: QuerySelect -> QuerySelect -> Bool
$c> :: QuerySelect -> QuerySelect -> Bool
> :: QuerySelect -> QuerySelect -> Bool
$c>= :: QuerySelect -> QuerySelect -> Bool
>= :: QuerySelect -> QuerySelect -> Bool
$cmax :: QuerySelect -> QuerySelect -> QuerySelect
max :: QuerySelect -> QuerySelect -> QuerySelect
$cmin :: QuerySelect -> QuerySelect -> QuerySelect
min :: QuerySelect -> QuerySelect -> QuerySelect
Ord,Typeable)


instance Default QuerySelect where def :: QuerySelect
def = QuerySelect
SelectAll

-------------------------------------------------------------------------------
querySelectJson :: KeyValue A.Value t => QuerySelect -> [t]
querySelectJson :: forall t. KeyValue Value t => QuerySelect -> [t]
querySelectJson (SelectSpecific [Text]
as) =
    [ Key
"Select" Key -> Value -> t
forall v. ToJSON v => Key -> v -> t
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String Text
"SPECIFIC_ATTRIBUTES"
    , Key
"AttributesToGet" Key -> [Text] -> t
forall v. ToJSON v => Key -> v -> t
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Text]
as]
querySelectJson QuerySelect
SelectCount = [Key
"Select" Key -> Value -> t
forall v. ToJSON v => Key -> v -> t
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String Text
"COUNT"]
querySelectJson QuerySelect
SelectProjected = [Key
"Select" Key -> Value -> t
forall v. ToJSON v => Key -> v -> t
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String Text
"ALL_PROJECTED_ATTRIBUTES"]
querySelectJson QuerySelect
SelectAll = [Key
"Select" Key -> Value -> t
forall v. ToJSON v => Key -> v -> t
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text -> Value
String Text
"ALL_ATTRIBUTES"]


-------------------------------------------------------------------------------
-- | A class to help predict DynamoDb size of values, attributes and
-- entire items. The result is given in number of bytes.
class DynSize a where
    dynSize :: a -> Int

instance DynSize DValue where
    dynSize :: DValue -> Int
dynSize DValue
DNull = Int
8
    dynSize (DBool Bool
_) = Int
8
    dynSize (DBoolSet Set Bool
s) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (Bool -> Int) -> [Bool] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (DValue -> Int
forall a. DynSize a => a -> Int
dynSize (DValue -> Int) -> (Bool -> DValue) -> Bool -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> DValue
DBool) ([Bool] -> [Int]) -> [Bool] -> [Int]
forall a b. (a -> b) -> a -> b
$ Set Bool -> [Bool]
forall a. Set a -> [a]
S.toList Set Bool
s
    dynSize (DNum Scientific
_) = Int
8
    dynSize (DString Text
a) = Text -> Int
T.length Text
a
    dynSize (DBinary ByteString
bs) = Text -> Int
T.length (Text -> Int) -> (ByteString -> Text) -> ByteString -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
T.decodeUtf8 (ByteString -> Int) -> ByteString -> Int
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
Base64.encode ByteString
bs
    dynSize (DNumSet Set Scientific
s) = Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Set Scientific -> Int
forall a. Set a -> Int
S.size Set Scientific
s
    dynSize (DStringSet Set Text
s) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (Text -> Int) -> [Text] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (DValue -> Int
forall a. DynSize a => a -> Int
dynSize (DValue -> Int) -> (Text -> DValue) -> Text -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> DValue
DString) ([Text] -> [Int]) -> [Text] -> [Int]
forall a b. (a -> b) -> a -> b
$ Set Text -> [Text]
forall a. Set a -> [a]
S.toList Set Text
s
    dynSize (DBinSet Set ByteString
s) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (ByteString -> Int) -> [ByteString] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (DValue -> Int
forall a. DynSize a => a -> Int
dynSize (DValue -> Int) -> (ByteString -> DValue) -> ByteString -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> DValue
DBinary) ([ByteString] -> [Int]) -> [ByteString] -> [Int]
forall a b. (a -> b) -> a -> b
$ Set ByteString -> [ByteString]
forall a. Set a -> [a]
S.toList Set ByteString
s
    dynSize (DList Vector DValue
s) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (DValue -> Int) -> [DValue] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map DValue -> Int
forall a. DynSize a => a -> Int
dynSize ([DValue] -> [Int]) -> [DValue] -> [Int]
forall a b. (a -> b) -> a -> b
$ Vector DValue -> [DValue]
forall a. Vector a -> [a]
V.toList Vector DValue
s
    dynSize (DMap Map Text DValue
s) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (DValue -> Int) -> [DValue] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map DValue -> Int
forall a. DynSize a => a -> Int
dynSize ([DValue] -> [Int]) -> [DValue] -> [Int]
forall a b. (a -> b) -> a -> b
$ Map Text DValue -> [DValue]
forall k a. Map k a -> [a]
M.elems Map Text DValue
s

instance DynSize Attribute where
    dynSize :: Attribute -> Int
dynSize (Attribute Text
k DValue
v) = Text -> Int
T.length Text
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ DValue -> Int
forall a. DynSize a => a -> Int
dynSize DValue
v

instance DynSize Item where
    dynSize :: Map Text DValue -> Int
dynSize Map Text DValue
m = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (Attribute -> Int) -> [Attribute] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Attribute -> Int
forall a. DynSize a => a -> Int
dynSize ([Attribute] -> [Int]) -> [Attribute] -> [Int]
forall a b. (a -> b) -> a -> b
$ Map Text DValue -> [Attribute]
attributes Map Text DValue
m

instance DynSize a => DynSize [a] where
    dynSize :: [a] -> Int
dynSize [a]
as = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (a -> Int) -> [a] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map a -> Int
forall a. DynSize a => a -> Int
dynSize [a]
as

instance DynSize a => DynSize (Maybe a) where
    dynSize :: Maybe a -> Int
dynSize = Int -> (a -> Int) -> Maybe a -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 a -> Int
forall a. DynSize a => a -> Int
dynSize

instance (DynSize a, DynSize b) => DynSize (Either a b) where
    dynSize :: Either a b -> Int
dynSize = (a -> Int) -> (b -> Int) -> Either a b -> Int
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either a -> Int
forall a. DynSize a => a -> Int
dynSize b -> Int
forall a. DynSize a => a -> Int
dynSize


-------------------------------------------------------------------------------
-- | Will an attribute be considered empty by DynamoDb?
--
-- A 'PutItem' (or similar) with empty attributes will be rejected
-- with a 'ValidationException'.
nullAttr :: Attribute -> Bool
nullAttr :: Attribute -> Bool
nullAttr (Attribute Text
_ DValue
val) =
    case DValue
val of
      DString Text
"" -> Bool
True
      DBinary ByteString
"" -> Bool
True
      DNumSet Set Scientific
s | Set Scientific -> Bool
forall a. Set a -> Bool
S.null Set Scientific
s -> Bool
True
      DStringSet Set Text
s | Set Text -> Bool
forall a. Set a -> Bool
S.null Set Text
s -> Bool
True
      DBinSet Set ByteString
s | Set ByteString -> Bool
forall a. Set a -> Bool
S.null Set ByteString
s -> Bool
True
      DValue
_ -> Bool
False




-------------------------------------------------------------------------------
--
-- | Item Parsing
--
-------------------------------------------------------------------------------



-- | Failure continuation.
type Failure f r   = String -> f r

-- | Success continuation.
type Success a f r = a -> f r


-- | A continuation-based parser type.
newtype Parser a = Parser {
      forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser :: forall f r.
                   Failure f r
                -> Success a f r
                -> f r
    }

instance Monad Parser where
    Parser a
m >>= :: forall a b. Parser a -> (a -> Parser b) -> Parser b
>>= a -> Parser b
g = (forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
-> Parser b
forall a.
(forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
Parser ((forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
 -> Parser b)
-> (forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
-> Parser b
forall a b. (a -> b) -> a -> b
$ \Failure f r
kf Success b f r
ks -> let ks' :: a -> f r
ks' a
a = Parser b
-> forall (f :: * -> *) r. Failure f r -> Success b f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser (a -> Parser b
g a
a) Failure f r
kf Success b f r
ks
                                 in Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser Parser a
m Failure f r
kf a -> f r
ks'
    {-# INLINE (>>=) #-}
    return :: forall a. a -> Parser a
return a
a = (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a.
(forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
Parser ((forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
 -> Parser a)
-> (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a b. (a -> b) -> a -> b
$ \Failure f r
_kf Success a f r
ks -> Success a f r
ks a
a
    {-# INLINE return #-}
#if !(MIN_VERSION_base(4,13,0))
    fail msg = Parser $ \kf _ks -> kf msg
    {-# INLINE fail #-}
#endif

#if MIN_VERSION_base(4,9,0)
instance Fail.MonadFail Parser where
    fail :: forall a. String -> Parser a
fail String
msg = (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a.
(forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
Parser ((forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
 -> Parser a)
-> (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a b. (a -> b) -> a -> b
$ \Failure f r
kf Success a f r
_ks -> Failure f r
kf String
msg
    {-# INLINE fail #-}
#endif

instance Functor Parser where
    fmap :: forall a b. (a -> b) -> Parser a -> Parser b
fmap a -> b
f Parser a
m = (forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
-> Parser b
forall a.
(forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
Parser ((forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
 -> Parser b)
-> (forall (f :: * -> *) r. Failure f r -> Success b f r -> f r)
-> Parser b
forall a b. (a -> b) -> a -> b
$ \Failure f r
kf Success b f r
ks -> let ks' :: a -> f r
ks' a
a = Success b f r
ks (a -> b
f a
a)
                                  in Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser Parser a
m Failure f r
kf a -> f r
ks'
    {-# INLINE fmap #-}

instance Applicative Parser where
    pure :: forall a. a -> Parser a
pure  = a -> Parser a
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return
    {-# INLINE pure #-}
    <*> :: forall a b. Parser (a -> b) -> Parser a -> Parser b
(<*>) = Parser (a -> b) -> Parser a -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
apP
    {-# INLINE (<*>) #-}

instance Alternative Parser where
    empty :: forall a. Parser a
empty = String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"empty"
    {-# INLINE empty #-}
    <|> :: forall a. Parser a -> Parser a -> Parser a
(<|>) = Parser a -> Parser a -> Parser a
forall a. Parser a -> Parser a -> Parser a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
    {-# INLINE (<|>) #-}

instance MonadPlus Parser where
    mzero :: forall a. Parser a
mzero = String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"mzero"
    {-# INLINE mzero #-}
    mplus :: forall a. Parser a -> Parser a -> Parser a
mplus Parser a
a Parser a
b = (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a.
(forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
Parser ((forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
 -> Parser a)
-> (forall (f :: * -> *) r. Failure f r -> Success a f r -> f r)
-> Parser a
forall a b. (a -> b) -> a -> b
$ \Failure f r
kf Success a f r
ks -> let kf' :: Failure f r
kf' String
_ = Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser Parser a
b Failure f r
kf Success a f r
ks
                                   in Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser Parser a
a Failure f r
kf' Success a f r
ks
    {-# INLINE mplus #-}

instance Sem.Semigroup (Parser a) where
    <> :: Parser a -> Parser a -> Parser a
(<>) = Parser a -> Parser a -> Parser a
forall a. Parser a -> Parser a -> Parser a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
    {-# INLINE (<>) #-}

instance Monoid (Parser a) where
    mempty :: Parser a
mempty  = String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"mempty"
    {-# INLINE mempty #-}
    mappend :: Parser a -> Parser a -> Parser a
mappend = Parser a -> Parser a -> Parser a
forall a. Semigroup a => a -> a -> a
(Sem.<>)
    {-# INLINE mappend #-}

apP :: Parser (a -> b) -> Parser a -> Parser b
apP :: forall a b. Parser (a -> b) -> Parser a -> Parser b
apP Parser (a -> b)
d Parser a
e = do
  a -> b
b <- Parser (a -> b)
d
  a
a <- Parser a
e
  b -> Parser b
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
b a
a)
{-# INLINE apP #-}


-------------------------------------------------------------------------------
-- | Types convertible to DynamoDb 'Item' collections.
--
-- Use 'attr' and 'attrAs' combinators to conveniently define instances.
class ToDynItem a where
    toItem :: a -> Item


-------------------------------------------------------------------------------
-- | Types parseable from DynamoDb 'Item' collections.
--
-- User 'getAttr' family of functions to applicatively or monadically
-- parse into your custom types.
class FromDynItem a where
    parseItem :: Item -> Parser a


instance ToDynItem Item where toItem :: Map Text DValue -> Map Text DValue
toItem = Map Text DValue -> Map Text DValue
forall a. a -> a
id

instance FromDynItem Item where parseItem :: Map Text DValue -> Parser (Map Text DValue)
parseItem = Map Text DValue -> Parser (Map Text DValue)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return


instance DynVal a => ToDynItem [(T.Text, a)] where
    toItem :: [(Text, a)] -> Map Text DValue
toItem [(Text, a)]
as = [Attribute] -> Map Text DValue
item ([Attribute] -> Map Text DValue) -> [Attribute] -> Map Text DValue
forall a b. (a -> b) -> a -> b
$ ((Text, a) -> Attribute) -> [(Text, a)] -> [Attribute]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> a -> Attribute) -> (Text, a) -> Attribute
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> a -> Attribute
forall a. DynVal a => Text -> a -> Attribute
attr) [(Text, a)]
as

instance (Typeable a, DynVal a) => FromDynItem [(T.Text, a)] where
    parseItem :: Map Text DValue -> Parser [(Text, a)]
parseItem Map Text DValue
i = ((Text, DValue) -> Parser (Text, a))
-> [(Text, DValue)] -> Parser [(Text, a)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Text, DValue) -> Parser (Text, a)
f ([(Text, DValue)] -> Parser [(Text, a)])
-> [(Text, DValue)] -> Parser [(Text, a)]
forall a b. (a -> b) -> a -> b
$ Map Text DValue -> [(Text, DValue)]
forall k a. Map k a -> [(k, a)]
M.toList Map Text DValue
i
        where
          f :: (Text, DValue) -> Parser (Text, a)
f (Text
k,DValue
v) = do
              a
v' <- Parser a -> (a -> Parser a) -> Maybe a -> Parser a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (Tagged a DValue -> String
forall a. Typeable a => Tagged a DValue -> String
valErr (DValue -> Tagged a DValue
forall {k} (s :: k) b. b -> Tagged s b
Tagged DValue
v :: Tagged a DValue))) a -> Parser a
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> Parser a) -> Maybe a -> Parser a
forall a b. (a -> b) -> a -> b
$
                    DValue -> Maybe a
forall a. DynVal a => DValue -> Maybe a
fromValue DValue
v
              (Text, a) -> Parser (Text, a)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Text
k, a
v')


instance DynVal a => ToDynItem (M.Map T.Text a) where
    toItem :: Map Text a -> Map Text DValue
toItem Map Text a
m = [(Text, a)] -> Map Text DValue
forall a. ToDynItem a => a -> Map Text DValue
toItem ([(Text, a)] -> Map Text DValue) -> [(Text, a)] -> Map Text DValue
forall a b. (a -> b) -> a -> b
$ Map Text a -> [(Text, a)]
forall k a. Map k a -> [(k, a)]
M.toList Map Text a
m


instance (Typeable a, DynVal a) => FromDynItem (M.Map T.Text a) where
    parseItem :: Map Text DValue -> Parser (Map Text a)
parseItem Map Text DValue
i = [(Text, a)] -> Map Text a
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Text, a)] -> Map Text a)
-> Parser [(Text, a)] -> Parser (Map Text a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Text DValue -> Parser [(Text, a)]
forall a. FromDynItem a => Map Text DValue -> Parser a
parseItem Map Text DValue
i


valErr :: forall a. Typeable a => Tagged a DValue -> String
valErr :: forall a. Typeable a => Tagged a DValue -> String
valErr (Tagged DValue
dv) = String
"Can't convert DynamoDb value " String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> DValue -> String
forall a. Show a => a -> String
show DValue
dv String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<>
              String
" into type " String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> (TypeRep -> String
forall a. Show a => a -> String
show (a -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf (a
forall a. HasCallStack => a
undefined :: a)))


-- | Convenience combinator for parsing fields from an 'Item' returned
-- by DynamoDb.
getAttr
    :: forall a. (Typeable a, DynVal a)
    => T.Text
    -- ^ Attribute name
    -> Item
    -- ^ Item from DynamoDb
    -> Parser a
getAttr :: forall a.
(Typeable a, DynVal a) =>
Text -> Map Text DValue -> Parser a
getAttr Text
k Map Text DValue
m = do
    case Text -> Map Text DValue -> Maybe DValue
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
k Map Text DValue
m of
      Maybe DValue
Nothing -> String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Key " String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> Text -> String
T.unpack Text
k String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> String
" not found")
      Just DValue
dv -> Parser a -> (a -> Parser a) -> Maybe a -> Parser a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (Tagged a DValue -> String
forall a. Typeable a => Tagged a DValue -> String
valErr (DValue -> Tagged a DValue
forall {k} (s :: k) b. b -> Tagged s b
Tagged DValue
dv :: Tagged a DValue))) a -> Parser a
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> Parser a) -> Maybe a -> Parser a
forall a b. (a -> b) -> a -> b
$ DValue -> Maybe a
forall a. DynVal a => DValue -> Maybe a
fromValue DValue
dv


-- | Parse attribute if it's present in the 'Item'. Fail if attribute
-- is present but conversion fails.
getAttr'
    :: forall a. (DynVal a)
    => T.Text
    -- ^ Attribute name
    -> Item
    -- ^ Item from DynamoDb
    -> Parser (Maybe a)
getAttr' :: forall a. DynVal a => Text -> Map Text DValue -> Parser (Maybe a)
getAttr' Text
k Map Text DValue
m = do
    case Text -> Map Text DValue -> Maybe DValue
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
k Map Text DValue
m of
      Maybe DValue
Nothing -> Maybe a -> Parser (Maybe a)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
      Just DValue
dv -> Maybe a -> Parser (Maybe a)
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> Parser (Maybe a)) -> Maybe a -> Parser (Maybe a)
forall a b. (a -> b) -> a -> b
$ DValue -> Maybe a
forall a. DynVal a => DValue -> Maybe a
fromValue DValue
dv

-- | Combinator for parsing an attribute into a 'FromDynItem'.
parseAttr
    :: FromDynItem a
    => T.Text
    -- ^ Attribute name
    -> Item
    -- ^ Item from DynamoDb
    -> Parser a
parseAttr :: forall a. FromDynItem a => Text -> Map Text DValue -> Parser a
parseAttr Text
k Map Text DValue
m =
  case Text -> Map Text DValue -> Maybe DValue
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Text
k Map Text DValue
m of
    Maybe DValue
Nothing -> String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Key " String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> Text -> String
T.unpack Text
k String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> String
" not found")
    Just (DMap Map Text DValue
dv) -> (String -> Parser a)
-> (a -> Parser a) -> Either String a -> Parser a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Parser a -> String -> Parser a
forall a b. a -> b -> a
const (String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"...")) a -> Parser a
forall a. a -> Parser a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String a -> Parser a) -> Either String a -> Parser a
forall a b. (a -> b) -> a -> b
$ Map Text DValue -> Either String a
forall a. FromDynItem a => Map Text DValue -> Either String a
fromItem Map Text DValue
dv
    Maybe DValue
_       -> String -> Parser a
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"Key " String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> Text -> String
T.unpack Text
k String -> ShowS
forall a. Semigroup a => a -> a -> a
Sem.<> String
" is not a map!")

-------------------------------------------------------------------------------
-- | Parse an 'Item' into target type using the 'FromDynItem'
-- instance.
fromItem :: FromDynItem a => Item -> Either String a
fromItem :: forall a. FromDynItem a => Map Text DValue -> Either String a
fromItem Map Text DValue
i = Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
forall a.
Parser a
-> forall (f :: * -> *) r. Failure f r -> Success a f r -> f r
runParser (Map Text DValue -> Parser a
forall a. FromDynItem a => Map Text DValue -> Parser a
parseItem Map Text DValue
i) Failure (Either String) a
forall a b. a -> Either a b
Left Success a (Either String) a
forall a b. b -> Either a b
Right