module Hasql.Encoders.Value where

import Hasql.PostgresTypeInfo qualified as PTI
import Hasql.Prelude
import PostgreSQL.Binary.Encoding qualified as B
import Text.Builder qualified as C

data Value a
  = Value PTI.OID PTI.OID (Bool -> a -> B.Encoding) (a -> C.Builder)

instance Contravariant Value where
  {-# INLINE contramap #-}
  contramap :: forall a' a. (a' -> a) -> Value a -> Value a'
contramap a' -> a
f (Value OID
valueOID OID
arrayOID Bool -> a -> Encoding
encode a -> Builder
render) =
    OID
-> OID -> (Bool -> a' -> Encoding) -> (a' -> Builder) -> Value a'
forall a.
OID -> OID -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
Value OID
valueOID OID
arrayOID (\Bool
integerDatetimes a'
input -> Bool -> a -> Encoding
encode Bool
integerDatetimes (a' -> a
f a'
input)) (a -> Builder
render (a -> Builder) -> (a' -> a) -> a' -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a' -> a
f)

{-# INLINE unsafePTI #-}
unsafePTI :: PTI.PTI -> (Bool -> a -> B.Encoding) -> (a -> C.Builder) -> Value a
unsafePTI :: forall a.
PTI -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
unsafePTI PTI
pti =
  OID -> OID -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
forall a.
OID -> OID -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
Value (PTI -> OID
PTI.ptiOID PTI
pti) (OID -> Maybe OID -> OID
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> OID
forall a. HasCallStack => [Char] -> a
error [Char]
"No array OID") (PTI -> Maybe OID
PTI.ptiArrayOID PTI
pti))

{-# INLINE unsafePTIWithShow #-}
unsafePTIWithShow :: (Show a) => PTI.PTI -> (Bool -> a -> B.Encoding) -> Value a
unsafePTIWithShow :: forall a. Show a => PTI -> (Bool -> a -> Encoding) -> Value a
unsafePTIWithShow PTI
pti Bool -> a -> Encoding
encode =
  PTI -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
forall a.
PTI -> (Bool -> a -> Encoding) -> (a -> Builder) -> Value a
unsafePTI PTI
pti Bool -> a -> Encoding
encode ([Char] -> Builder
C.string ([Char] -> Builder) -> (a -> [Char]) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> [Char]
forall a. Show a => a -> [Char]
show)