{-# LANGUAGE BlockArguments #-}

module Data.RdsData.Encode.Value
  ( EncodeValue(..)

  , rdsValue

  , maybe

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

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

import Data.ByteString (ByteString)
import Data.Functor.Contravariant
import Data.Int
import Data.RdsData.Encode.Array
import Data.RdsData.Types.Value
import Data.Text (Text)
import Data.Time
import Data.ULID (ULID)
import Data.UUID (UUID)
import Data.Word
import Prelude hiding (maybe, null)

import qualified Amazonka.Bytes                 as AWS
import qualified Amazonka.Data.Base64           as AWS
import qualified Data.Aeson                     as J
import qualified Data.ByteString.Lazy           as LBS
import qualified Data.RdsData.Internal.Convert  as CONV
import qualified Data.Text.Lazy                 as LT
import qualified Prelude                        as P

newtype EncodeValue a = EncodeValue
  { forall a. EncodeValue a -> a -> Value
encodeValue :: a -> Value
  }

instance Contravariant EncodeValue where
  contramap :: forall a' a. (a' -> a) -> EncodeValue a -> EncodeValue a'
contramap a' -> a
f (EncodeValue a -> Value
g) =
    (a' -> Value) -> EncodeValue a'
forall a. (a -> Value) -> EncodeValue a
EncodeValue (a -> Value
g (a -> Value) -> (a' -> a) -> a' -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f)

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

rdsValue :: EncodeValue Value
rdsValue :: EncodeValue Value
rdsValue =
  (Value -> Value) -> EncodeValue Value
forall a. (a -> Value) -> EncodeValue a
EncodeValue Value -> Value
forall a. a -> a
id

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

maybe :: EncodeValue a -> EncodeValue (Maybe a)
maybe :: forall a. EncodeValue a -> EncodeValue (Maybe a)
maybe =
  (Maybe a -> Value) -> EncodeValue (Maybe a)
forall a. (a -> Value) -> EncodeValue a
EncodeValue ((Maybe a -> Value) -> EncodeValue (Maybe a))
-> (EncodeValue a -> Maybe a -> Value)
-> EncodeValue a
-> EncodeValue (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> (a -> Value) -> Maybe a -> Value
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe Value
ValueOfNull ((a -> Value) -> Maybe a -> Value)
-> (EncodeValue a -> a -> Value)
-> EncodeValue a
-> Maybe a
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EncodeValue a -> a -> Value
forall a. EncodeValue a -> a -> Value
encodeValue

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

array :: EncodeArray a -> EncodeValue a
array :: forall a. EncodeArray a -> EncodeValue a
array EncodeArray a
enc =
  Array -> Value
ValueOfArray (Array -> Value) -> (a -> Array) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EncodeArray a -> a -> Array
forall a. EncodeArray a -> a -> Array
encodeArray EncodeArray a
enc (a -> Value) -> EncodeValue Value -> EncodeValue a
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

base64 :: EncodeValue AWS.Base64
base64 :: EncodeValue Base64
base64 =
  Base64 -> Value
ValueOfBase64 (Base64 -> Value) -> EncodeValue Value -> EncodeValue Base64
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

bool :: EncodeValue Bool
bool :: EncodeValue Bool
bool =
  Bool -> Value
ValueOfBool (Bool -> Value) -> EncodeValue Value -> EncodeValue Bool
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

double :: EncodeValue Double
double :: EncodeValue Double
double =
  Double -> Value
ValueOfDouble (Double -> Value) -> EncodeValue Value -> EncodeValue Double
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

null :: EncodeValue ()
null :: EncodeValue ()
null =
  Value -> () -> Value
forall a b. a -> b -> a
const Value
ValueOfNull (() -> Value) -> EncodeValue Value -> EncodeValue ()
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

integer :: EncodeValue Integer
integer :: EncodeValue Integer
integer =
  Integer -> Value
ValueOfInteger (Integer -> Value) -> EncodeValue Value -> EncodeValue Integer
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

text :: EncodeValue Text
text :: EncodeValue Text
text =
  Text -> Value
ValueOfText (Text -> Value) -> EncodeValue Value -> EncodeValue Text
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Value
rdsValue

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

int :: EncodeValue Int
int :: EncodeValue Int
int =
  Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Integer) -> EncodeValue Integer -> EncodeValue Int
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

int8 :: EncodeValue Int8
int8 :: EncodeValue Int8
int8 =
  Int8 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8 -> Integer) -> EncodeValue Integer -> EncodeValue Int8
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

int16 :: EncodeValue Int16
int16 :: EncodeValue Int16
int16 =
  Int16 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int16 -> Integer) -> EncodeValue Integer -> EncodeValue Int16
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

int32 :: EncodeValue Int32
int32 :: EncodeValue Int32
int32 =
  Int32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32 -> Integer) -> EncodeValue Integer -> EncodeValue Int32
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

int64 :: EncodeValue Int64
int64 :: EncodeValue Int64
int64 =
  Int64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int64 -> Integer) -> EncodeValue Integer -> EncodeValue Int64
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

word :: EncodeValue Word
word :: EncodeValue Word
word =
  Word -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Integer) -> EncodeValue Integer -> EncodeValue Word
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

word8 :: EncodeValue Word8
word8 :: EncodeValue Word8
word8 =
  Word8 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Integer) -> EncodeValue Integer -> EncodeValue Word8
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

word16 :: EncodeValue Word16
word16 :: EncodeValue Word16
word16 =
  Word16 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16 -> Integer) -> EncodeValue Integer -> EncodeValue Word16
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

word32 :: EncodeValue Word32
word32 :: EncodeValue Word32
word32 =
  Word32 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Integer) -> EncodeValue Integer -> EncodeValue Word32
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

word64 :: EncodeValue Word64
word64 :: EncodeValue Word64
word64 =
  Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> Integer) -> EncodeValue Integer -> EncodeValue Word64
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Integer
integer

lazyText :: EncodeValue LT.Text
lazyText :: EncodeValue Text
lazyText =
  Text -> Text
LT.toStrict (Text -> Text) -> EncodeValue Text -> EncodeValue Text
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

bytestring :: EncodeValue ByteString
bytestring :: EncodeValue ByteString
bytestring =
  (ByteString -> Base64
AWS.Base64 (ByteString -> Base64)
-> (ByteString -> ByteString) -> ByteString -> Base64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
AWS.encodeBase64) (ByteString -> Base64)
-> EncodeValue Base64 -> EncodeValue ByteString
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Base64
base64

lazyBytestring :: EncodeValue LBS.ByteString
lazyBytestring :: EncodeValue ByteString
lazyBytestring =
  ByteString -> ByteString
LBS.toStrict (ByteString -> ByteString)
-> EncodeValue ByteString -> EncodeValue ByteString
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue ByteString
bytestring

timeOfDay :: EncodeValue TimeOfDay
timeOfDay :: EncodeValue TimeOfDay
timeOfDay =
  TimeOfDay -> Text
CONV.timeOfDayToText (TimeOfDay -> Text) -> EncodeValue Text -> EncodeValue TimeOfDay
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

day :: EncodeValue Day
day :: EncodeValue Day
day =
  Day -> Text
CONV.dayToText (Day -> Text) -> EncodeValue Text -> EncodeValue Day
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

json :: EncodeValue J.Value
json :: EncodeValue Value
json =
  Value -> Text
CONV.jsonToText (Value -> Text) -> EncodeValue Text -> EncodeValue Value
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

utcTime :: EncodeValue UTCTime
utcTime :: EncodeValue UTCTime
utcTime =
  UTCTime -> Text
CONV.utcTimeToText (UTCTime -> Text) -> EncodeValue Text -> EncodeValue UTCTime
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

ulid :: EncodeValue ULID
ulid :: EncodeValue ULID
ulid =
  ULID -> Text
CONV.ulidToText (ULID -> Text) -> EncodeValue Text -> EncodeValue ULID
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text

uuid :: EncodeValue UUID
uuid :: EncodeValue UUID
uuid =
  UUID -> Text
CONV.uuidToText (UUID -> Text) -> EncodeValue Text -> EncodeValue UUID
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
>$< EncodeValue Text
text