{-# LANGUAGE BlockArguments #-}

module Data.RdsData.Encode.Params
  ( EncodeParams(..)

  , rdsValue

  , column

  , maybe

  , array
  , bool
  , bytestring
  , double
  , integer
  , null
  , text

  , base64
  , day
  , int
  , int8
  , int16
  , int32
  , int64
  , json
  , lazyBytestring
  , lazyText
  , timeOfDay
  , ulid
  , utcTime
  , uuid
  , word
  , word8
  , word16
  , word32
  , word64
  ) where

import Data.ByteString (ByteString)
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Divisible
import Data.Int
import Data.RdsData.Encode.Array (EncodeArray(..))
import Data.RdsData.Encode.Param (EncodeParam(..))
import Data.RdsData.Types.Param
import Data.Text (Text)
import Data.Time
import Data.UUID (UUID)
import Data.ULID (ULID)
import Data.Void
import Data.Word
import Prelude hiding (maybe, null)

import qualified Amazonka.Data.Base64       as AWS
import qualified Data.Aeson                 as J
import qualified Data.ByteString.Lazy       as LBS
import qualified Data.RdsData.Encode.Param  as EP
import qualified Data.Text.Lazy             as LT
import qualified Prelude                    as P

newtype EncodeParams a = EncodeParams
  { forall a. EncodeParams a -> a -> [Param] -> [Param]
encodeParams :: a -> [Param] -> [Param]
  }

instance Contravariant EncodeParams where
  contramap :: forall a' a. (a' -> a) -> EncodeParams a -> EncodeParams a'
contramap a' -> a
f (EncodeParams a -> [Param] -> [Param]
g) =
    (a' -> [Param] -> [Param]) -> EncodeParams a'
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams (a -> [Param] -> [Param]
g (a -> [Param] -> [Param]) -> (a' -> a) -> a' -> [Param] -> [Param]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f)

instance Divisible EncodeParams where
  divide :: forall a b c.
(a -> (b, c)) -> EncodeParams b -> EncodeParams c -> EncodeParams a
divide a -> (b, c)
f (EncodeParams b -> [Param] -> [Param]
g) (EncodeParams c -> [Param] -> [Param]
h) =
    (a -> [Param] -> [Param]) -> EncodeParams a
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams \a
a ->
      case a -> (b, c)
f a
a of
        (b
b, c
c) -> b -> [Param] -> [Param]
g b
b ([Param] -> [Param]) -> ([Param] -> [Param]) -> [Param] -> [Param]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> [Param] -> [Param]
h c
c
  conquer :: forall a. EncodeParams a
conquer =
    (a -> [Param] -> [Param]) -> EncodeParams a
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams ((a -> [Param] -> [Param]) -> EncodeParams a)
-> (a -> [Param] -> [Param]) -> EncodeParams a
forall a b. (a -> b) -> a -> b
$ ([Param] -> [Param]) -> a -> [Param] -> [Param]
forall a b. a -> b -> a
const [Param] -> [Param]
forall a. a -> a
id

instance Decidable EncodeParams where
  choose :: forall a b c.
(a -> Either b c)
-> EncodeParams b -> EncodeParams c -> EncodeParams a
choose a -> Either b c
f (EncodeParams b -> [Param] -> [Param]
g) (EncodeParams c -> [Param] -> [Param]
h) =
    (a -> [Param] -> [Param]) -> EncodeParams a
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams \a
a ->
      case a -> Either b c
f a
a of
        Left b
b -> b -> [Param] -> [Param]
g b
b
        Right c
c -> c -> [Param] -> [Param]
h c
c
  lose :: forall a. (a -> Void) -> EncodeParams a
lose a -> Void
f =
    (a -> [Param] -> [Param]) -> EncodeParams a
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams ((a -> [Param] -> [Param]) -> EncodeParams a)
-> (a -> [Param] -> [Param]) -> EncodeParams a
forall a b. (a -> b) -> a -> b
$ Void -> [Param] -> [Param]
forall a. Void -> a
absurd (Void -> [Param] -> [Param])
-> (a -> Void) -> a -> [Param] -> [Param]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Void
f

--------------------------------------------------------------------------------

rdsValue :: EncodeParams Param
rdsValue :: EncodeParams Param
rdsValue =
  (Param -> [Param] -> [Param]) -> EncodeParams Param
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams (:)

--------------------------------------------------------------------------------

column :: EncodeParam a -> EncodeParams a
column :: forall a. EncodeParam a -> EncodeParams a
column (EncodeParam a -> Param
f) =
  (a -> [Param] -> [Param]) -> EncodeParams a
forall a. (a -> [Param] -> [Param]) -> EncodeParams a
EncodeParams \a
a -> (a -> Param
f a
aParam -> [Param] -> [Param]
forall a. a -> [a] -> [a]
:)

--------------------------------------------------------------------------------

maybe :: EncodeParams a -> EncodeParams (Maybe a)
maybe :: forall a. EncodeParams a -> EncodeParams (Maybe a)
maybe =
  (Maybe a -> Either () a)
-> EncodeParams () -> EncodeParams a -> EncodeParams (Maybe a)
forall a b c.
(a -> Either b c)
-> EncodeParams b -> EncodeParams c -> EncodeParams a
forall (f :: * -> *) a b c.
Decidable f =>
(a -> Either b c) -> f b -> f c -> f a
choose (Either () a -> (a -> Either () a) -> Maybe a -> Either () a
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe (() -> Either () a
forall a b. a -> Either a b
Left ()) a -> Either () a
forall a b. b -> Either a b
Right) EncodeParams ()
null

--------------------------------------------------------------------------------

array :: EncodeArray a -> EncodeParams a
array :: forall a. EncodeArray a -> EncodeParams a
array =
  EncodeParam a -> EncodeParams a
forall a. EncodeParam a -> EncodeParams a
column (EncodeParam a -> EncodeParams a)
-> (EncodeArray a -> EncodeParam a)
-> EncodeArray a
-> EncodeParams a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EncodeArray a -> EncodeParam a
forall a. EncodeArray a -> EncodeParam a
EP.array

base64 :: EncodeParams AWS.Base64
base64 :: EncodeParams Base64
base64 =
  EncodeParam Base64 -> EncodeParams Base64
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Base64
EP.base64

bool :: EncodeParams Bool
bool :: EncodeParams Bool
bool =
  EncodeParam Bool -> EncodeParams Bool
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Bool
EP.bool

double :: EncodeParams Double
double :: EncodeParams Double
double =
  EncodeParam Double -> EncodeParams Double
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Double
EP.double

null :: EncodeParams ()
null :: EncodeParams ()
null =
  EncodeParam () -> EncodeParams ()
forall a. EncodeParam a -> EncodeParams a
column EncodeParam ()
EP.null

integer :: EncodeParams Integer
integer :: EncodeParams Integer
integer =
  EncodeParam Integer -> EncodeParams Integer
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Integer
EP.integer

text :: EncodeParams Text
text :: EncodeParams Text
text =
  EncodeParam Text -> EncodeParams Text
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Text
EP.text

--------------------------------------------------------------------------------

int :: EncodeParams Int
int :: EncodeParams Int
int =
  EncodeParam Int -> EncodeParams Int
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Int
EP.int

int8 :: EncodeParams Int8
int8 :: EncodeParams Int8
int8 =
  EncodeParam Int8 -> EncodeParams Int8
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Int8
EP.int8

int16 :: EncodeParams Int16
int16 :: EncodeParams Int16
int16 =
  EncodeParam Int16 -> EncodeParams Int16
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Int16
EP.int16

int32 :: EncodeParams Int32
int32 :: EncodeParams Int32
int32 =
  EncodeParam Int32 -> EncodeParams Int32
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Int32
EP.int32

int64 :: EncodeParams Int64
int64 :: EncodeParams Int64
int64 =
  EncodeParam Int64 -> EncodeParams Int64
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Int64
EP.int64

word :: EncodeParams Word
word :: EncodeParams Word
word =
  EncodeParam Word -> EncodeParams Word
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Word
EP.word

word8 :: EncodeParams Word8
word8 :: EncodeParams Word8
word8 =
  EncodeParam Word8 -> EncodeParams Word8
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Word8
EP.word8

word16 :: EncodeParams Word16
word16 :: EncodeParams Word16
word16 =
  EncodeParam Word16 -> EncodeParams Word16
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Word16
EP.word16

word32 :: EncodeParams Word32
word32 :: EncodeParams Word32
word32 =
  EncodeParam Word32 -> EncodeParams Word32
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Word32
EP.word32

word64 :: EncodeParams Word64
word64 :: EncodeParams Word64
word64 =
  EncodeParam Word64 -> EncodeParams Word64
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Word64
EP.word64

lazyText :: EncodeParams LT.Text
lazyText :: EncodeParams Text
lazyText =
  EncodeParam Text -> EncodeParams Text
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Text
EP.lazyText

bytestring :: EncodeParams ByteString
bytestring :: EncodeParams ByteString
bytestring =
  EncodeParam ByteString -> EncodeParams ByteString
forall a. EncodeParam a -> EncodeParams a
column EncodeParam ByteString
EP.bytestring

lazyBytestring :: EncodeParams LBS.ByteString
lazyBytestring :: EncodeParams ByteString
lazyBytestring =
  EncodeParam ByteString -> EncodeParams ByteString
forall a. EncodeParam a -> EncodeParams a
column EncodeParam ByteString
EP.lazyBytestring

timeOfDay :: EncodeParams TimeOfDay
timeOfDay :: EncodeParams TimeOfDay
timeOfDay =
  EncodeParam TimeOfDay -> EncodeParams TimeOfDay
forall a. EncodeParam a -> EncodeParams a
column EncodeParam TimeOfDay
EP.timeOfDay

day :: EncodeParams Day
day :: EncodeParams Day
day =
  EncodeParam Day -> EncodeParams Day
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Day
EP.day

json :: EncodeParams J.Value
json :: EncodeParams Value
json =
  EncodeParam Value -> EncodeParams Value
forall a. EncodeParam a -> EncodeParams a
column EncodeParam Value
EP.json

ulid :: EncodeParams ULID
ulid :: EncodeParams ULID
ulid =
  EncodeParam ULID -> EncodeParams ULID
forall a. EncodeParam a -> EncodeParams a
column EncodeParam ULID
EP.ulid

utcTime :: EncodeParams UTCTime
utcTime :: EncodeParams UTCTime
utcTime =
  EncodeParam UTCTime -> EncodeParams UTCTime
forall a. EncodeParam a -> EncodeParams a
column EncodeParam UTCTime
EP.utcTime

uuid :: EncodeParams UUID
uuid :: EncodeParams UUID
uuid =
  EncodeParam UUID -> EncodeParams UUID
forall a. EncodeParam a -> EncodeParams a
column EncodeParam UUID
EP.uuid