module Hasql.Private.Encoders.Array where

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

data Array a
  = Array B.OID B.OID (Bool -> a -> A.Array) (a -> C.Builder)

instance Contravariant Array where
  contramap :: forall a' a. (a' -> a) -> Array a -> Array a'
contramap a' -> a
fn (Array OID
valueOid OID
arrayOid Bool -> a -> Array
encoder a -> Builder
renderer) =
    forall a.
OID -> OID -> (Bool -> a -> Array) -> (a -> Builder) -> Array a
Array OID
valueOid OID
arrayOid (\Bool
intDateTimes -> Bool -> a -> Array
encoder Bool
intDateTimes forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a' -> a
fn) (a -> Builder
renderer forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a' -> a
fn)

{-# INLINE value #-}
value :: B.OID -> B.OID -> (Bool -> a -> A.Encoding) -> (a -> C.Builder) -> Array a
value :: forall a.
OID -> OID -> (Bool -> a -> Encoding) -> (a -> Builder) -> Array a
value OID
valueOID OID
arrayOID Bool -> a -> Encoding
encoder =
  forall a.
OID -> OID -> (Bool -> a -> Array) -> (a -> Builder) -> Array a
Array OID
valueOID OID
arrayOID (\Bool
params -> Encoding -> Array
A.encodingArray forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Bool -> a -> Encoding
encoder Bool
params)

{-# INLINE nullableValue #-}
nullableValue :: B.OID -> B.OID -> (Bool -> a -> A.Encoding) -> (a -> C.Builder) -> Array (Maybe a)
nullableValue :: forall a.
OID
-> OID
-> (Bool -> a -> Encoding)
-> (a -> Builder)
-> Array (Maybe a)
nullableValue OID
valueOID OID
arrayOID Bool -> a -> Encoding
encoder a -> Builder
renderer =
  let maybeEncoder :: Bool -> Maybe a -> Array
maybeEncoder Bool
params =
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe Array
A.nullArray (Encoding -> Array
A.encodingArray forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Bool -> a -> Encoding
encoder Bool
params)
      maybeRenderer :: Maybe a -> Builder
maybeRenderer =
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Builder
C.string String
"null") a -> Builder
renderer
   in forall a.
OID -> OID -> (Bool -> a -> Array) -> (a -> Builder) -> Array a
Array OID
valueOID OID
arrayOID Bool -> Maybe a -> Array
maybeEncoder Maybe a -> Builder
maybeRenderer

{-# INLINE dimension #-}
dimension :: (forall a. (a -> b -> a) -> a -> c -> a) -> Array b -> Array c
dimension :: forall b c.
(forall a. (a -> b -> a) -> a -> c -> a) -> Array b -> Array c
dimension forall a. (a -> b -> a) -> a -> c -> a
fold (Array OID
valueOID OID
arrayOID Bool -> b -> Array
elEncoder b -> Builder
elRenderer) =
  let encoder :: Bool -> c -> Array
encoder Bool
el =
        forall a c.
(forall b. (b -> a -> b) -> b -> c -> b)
-> (a -> Array) -> c -> Array
A.dimensionArray forall a. (a -> b -> a) -> a -> c -> a
fold (Bool -> b -> Array
elEncoder Bool
el)
      renderer :: c -> Builder
renderer c
els =
        let folded :: Builder
folded =
              let step :: Builder -> b -> Builder
step Builder
builder b
el =
                    if Builder -> Bool
C.null Builder
builder
                      then Char -> Builder
C.char Char
'[' forall a. Semigroup a => a -> a -> a
<> b -> Builder
elRenderer b
el
                      else Builder
builder forall a. Semigroup a => a -> a -> a
<> String -> Builder
C.string String
", " forall a. Semigroup a => a -> a -> a
<> b -> Builder
elRenderer b
el
               in forall a. (a -> b -> a) -> a -> c -> a
fold Builder -> b -> Builder
step forall a. Monoid a => a
mempty c
els
         in if Builder -> Bool
C.null Builder
folded
              then String -> Builder
C.string String
"[]"
              else Builder
folded forall a. Semigroup a => a -> a -> a
<> Char -> Builder
C.char Char
']'
   in forall a.
OID -> OID -> (Bool -> a -> Array) -> (a -> Builder) -> Array a
Array OID
valueOID OID
arrayOID Bool -> c -> Array
encoder c -> Builder
renderer