module Hasql.Private.Encoders.Params where

import qualified Database.PostgreSQL.LibPQ as A
import qualified Hasql.Private.Encoders.Value as C
import qualified Hasql.Private.PTI as D
import Hasql.Private.Prelude
import qualified PostgreSQL.Binary.Encoding as B
import qualified Text.Builder as E

-- |
-- Encoder of some representation of a parameters product.
newtype Params a
  = Params (Op (DList (A.Oid, A.Format, Bool -> Maybe ByteString, Text)) a)
  deriving (b -> Params b -> Params a
(a -> b) -> Params b -> Params a
(forall a b. (a -> b) -> Params b -> Params a)
-> (forall b a. b -> Params b -> Params a) -> Contravariant Params
forall b a. b -> Params b -> Params a
forall a b. (a -> b) -> Params b -> Params a
forall (f :: * -> *).
(forall a b. (a -> b) -> f b -> f a)
-> (forall b a. b -> f b -> f a) -> Contravariant f
>$ :: b -> Params b -> Params a
$c>$ :: forall b a. b -> Params b -> Params a
contramap :: (a -> b) -> Params b -> Params a
$ccontramap :: forall a b. (a -> b) -> Params b -> Params a
Contravariant, Contravariant Params
Params a
Contravariant Params
-> (forall a b c.
    (a -> (b, c)) -> Params b -> Params c -> Params a)
-> (forall a. Params a)
-> Divisible Params
(a -> (b, c)) -> Params b -> Params c -> Params a
forall a. Params a
forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
forall (f :: * -> *).
Contravariant f
-> (forall a b c. (a -> (b, c)) -> f b -> f c -> f a)
-> (forall a. f a)
-> Divisible f
conquer :: Params a
$cconquer :: forall a. Params a
divide :: (a -> (b, c)) -> Params b -> Params c -> Params a
$cdivide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
$cp1Divisible :: Contravariant Params
Divisible, Divisible Params
Divisible Params
-> (forall a. (a -> Void) -> Params a)
-> (forall a b c.
    (a -> Either b c) -> Params b -> Params c -> Params a)
-> Decidable Params
(a -> Void) -> Params a
(a -> Either b c) -> Params b -> Params c -> Params a
forall a. (a -> Void) -> Params a
forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
forall (f :: * -> *).
Divisible f
-> (forall a. (a -> Void) -> f a)
-> (forall a b c. (a -> Either b c) -> f b -> f c -> f a)
-> Decidable f
choose :: (a -> Either b c) -> Params b -> Params c -> Params a
$cchoose :: forall a b c. (a -> Either b c) -> Params b -> Params c -> Params a
lose :: (a -> Void) -> Params a
$close :: forall a. (a -> Void) -> Params a
$cp1Decidable :: Divisible Params
Decidable, b -> Params a -> Params a
NonEmpty (Params a) -> Params a
Params a -> Params a -> Params a
(Params a -> Params a -> Params a)
-> (NonEmpty (Params a) -> Params a)
-> (forall b. Integral b => b -> Params a -> Params a)
-> Semigroup (Params a)
forall b. Integral b => b -> Params a -> Params a
forall a. NonEmpty (Params a) -> Params a
forall a. Params a -> Params a -> Params a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> Params a -> Params a
stimes :: b -> Params a -> Params a
$cstimes :: forall a b. Integral b => b -> Params a -> Params a
sconcat :: NonEmpty (Params a) -> Params a
$csconcat :: forall a. NonEmpty (Params a) -> Params a
<> :: Params a -> Params a -> Params a
$c<> :: forall a. Params a -> Params a -> Params a
Semigroup, Semigroup (Params a)
Params a
Semigroup (Params a)
-> Params a
-> (Params a -> Params a -> Params a)
-> ([Params a] -> Params a)
-> Monoid (Params a)
[Params a] -> Params a
Params a -> Params a -> Params a
forall a. Semigroup (Params a)
forall a. Params a
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. [Params a] -> Params a
forall a. Params a -> Params a -> Params a
mconcat :: [Params a] -> Params a
$cmconcat :: forall a. [Params a] -> Params a
mappend :: Params a -> Params a -> Params a
$cmappend :: forall a. Params a -> Params a -> Params a
mempty :: Params a
$cmempty :: forall a. Params a
$cp1Monoid :: forall a. Semigroup (Params a)
Monoid)

value :: C.Value a -> Params a
value :: Value a -> Params a
value =
  (a -> Maybe a) -> Params (Maybe a) -> Params a
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap a -> Maybe a
forall a. a -> Maybe a
Just (Params (Maybe a) -> Params a)
-> (Value a -> Params (Maybe a)) -> Value a -> Params a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Value a -> Params (Maybe a)
forall a. Value a -> Params (Maybe a)
nullableValue

nullableValue :: C.Value a -> Params (Maybe a)
nullableValue :: Value a -> Params (Maybe a)
nullableValue (C.Value OID
valueOID OID
arrayOID Bool -> a -> Encoding
encode a -> Builder
render) =
  Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
-> Params (Maybe a)
forall a.
Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) a
-> Params a
Params (Op (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
 -> Params (Maybe a))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
-> Params (Maybe a)
forall a b. (a -> b) -> a -> b
$
    (Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
forall a b. (b -> a) -> Op a b
Op ((Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
 -> Op
      (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a))
-> (Maybe a -> DList (Oid, Format, Bool -> Maybe ByteString, Text))
-> Op
     (DList (Oid, Format, Bool -> Maybe ByteString, Text)) (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Maybe a
input ->
      let D.OID Word32
_ Oid
pqOid Format
format =
            OID
valueOID
          encoder :: Bool -> Maybe ByteString
encoder Bool
env =
            (a -> ByteString) -> Maybe a -> Maybe ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Encoding -> ByteString
B.encodingBytes (Encoding -> ByteString) -> (a -> Encoding) -> a -> ByteString
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
encode Bool
env) Maybe a
input
          rendering :: Text
rendering =
            Text -> (a -> Text) -> Maybe a -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"null" (Builder -> Text
E.run (Builder -> Text) -> (a -> Builder) -> a -> Text
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> Builder
render) Maybe a
input
       in (Oid, Format, Bool -> Maybe ByteString, Text)
-> DList (Oid, Format, Bool -> Maybe ByteString, Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Oid
pqOid, Format
format, Bool -> Maybe ByteString
encoder, Text
rendering)