module Hasql.Codecs.Encoders.Params
  ( Params,
    noParams,
    param,
    toColumnsMetadata,
    toUnknownTypes,
    toSerializer,
    toPrinter,
  )
where

import Data.Vector qualified as Vector
import Hasql.Codecs.Encoders.NullableOrNot qualified as NullableOrNot
import Hasql.Codecs.Encoders.Value qualified as Value
import Hasql.CodecsVocab qualified as CodecsVocab
import Hasql.CodecsVocab.QualifiedTypeName qualified as CodecsVocab.QualifiedTypeName
import Hasql.CodecsVocab.TypeRef qualified as CodecsVocab.TypeRef
import Hasql.CodecsVocab.TypeShape (TypeShape (..))
import Hasql.Platform.Prelude
import Hasql.ToBeResolved qualified as ToBeResolved
import PostgreSQL.Binary.Encoding qualified as Binary
import TextBuilder qualified

-- | Frozen per-parameter type shapes: type reference, dimensionality, text-format flag.
toColumnsMetadata :: Params a -> Vector TypeShape
toColumnsMetadata :: forall a. Params a -> Vector TypeShape
toColumnsMetadata (Params Int
_ ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
_ DList TypeShape
columnsMetadata a -> DList Text
_) = DList TypeShape -> Vector (Item (DList TypeShape))
forall {a}. IsList a => a -> Vector (Item a)
freezeColumnsMetadata DList TypeShape
columnsMetadata
  where
    freezeColumnsMetadata :: a -> Vector (Item a)
freezeColumnsMetadata =
      [Item a] -> Vector (Item a)
forall a. [a] -> Vector a
Vector.fromList ([Item a] -> Vector (Item a))
-> (a -> [Item a]) -> a -> Vector (Item a)
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 -> [Item a]
forall l. IsList l => l -> [Item l]
toList

toUnknownTypes :: Params a -> HashSet CodecsVocab.QualifiedTypeName
toUnknownTypes :: forall a. Params a -> HashSet QualifiedTypeName
toUnknownTypes (Params Int
_ (ToBeResolved.ToBeResolved [QualifiedTypeName]
unknownTypes (QualifiedTypeName -> TypeInfo) -> a -> [Maybe ByteString]
_) DList TypeShape
_ a -> DList Text
_) =
  [Item (HashSet QualifiedTypeName)] -> HashSet QualifiedTypeName
forall l. IsList l => [Item l] -> l
fromList [Item (HashSet QualifiedTypeName)]
[QualifiedTypeName]
unknownTypes

-- | Serialise params to encoded wire values given a resolver of type names to their OIDs.
toSerializer :: Params a -> (CodecsVocab.QualifiedTypeName -> CodecsVocab.TypeInfo) -> a -> [Maybe ByteString]
toSerializer :: forall a.
Params a
-> (QualifiedTypeName -> TypeInfo) -> a -> [Maybe ByteString]
toSerializer (Params Int
_ (ToBeResolved.ToBeResolved [QualifiedTypeName]
_ (QualifiedTypeName -> TypeInfo) -> a -> [Maybe ByteString]
serializer) DList TypeShape
_ a -> DList Text
_) QualifiedTypeName -> TypeInfo
resolve = (QualifiedTypeName -> TypeInfo) -> a -> [Maybe ByteString]
serializer QualifiedTypeName -> TypeInfo
resolve

-- | Render params in human-readable form (for error reporting).
toPrinter :: Params a -> a -> [Text]
toPrinter :: forall a. Params a -> a -> [Text]
toPrinter (Params Int
_ ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
_ DList TypeShape
_ a -> DList Text
printer) = DList Text -> [Text]
DList Text -> [Item (DList Text)]
forall l. IsList l => l -> [Item l]
toList (DList Text -> [Text]) -> (a -> DList Text) -> a -> [Text]
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 -> DList Text
printer

-- |
-- Encoder of some representation of a parameters product.
--
-- Has instances of 'Contravariant', 'Divisible' and 'Monoid',
-- which you can use to compose multiple parameters together.
-- E.g.,
--
-- @
-- someParamsEncoder :: 'Params' (Int64, Maybe Text)
-- someParamsEncoder =
--   ('fst' '>$<' 'param' ('nonNullable' 'int8')) '<>'
--   ('snd' '>$<' 'param' ('nullable' 'text'))
-- @
--
-- As a general solution for tuples of any arity, instead of 'fst' and 'snd',
-- consider the functions of the @contrazip@ family
-- from the "contravariant-extras" package.
-- E.g., here's how you can achieve the same as the above:
--
-- @
-- someParamsEncoder :: 'Params' (Int64, Maybe Text)
-- someParamsEncoder =
--   'contrazip2' ('param' ('nonNullable' 'int8')) ('param' ('nullable' 'text'))
-- @
--
-- Here's how you can implement encoders for custom composite types:
--
-- @
-- data Person = Person { name :: Text, gender :: Gender, age :: Int }
--
-- data Gender = Male | Female
--
-- personParams :: 'Params' Person
-- personParams =
--   (name '>$<' 'param' ('nonNullable' 'text')) '<>'
--   (gender '>$<' 'param' ('nonNullable' genderValue)) '<>'
--   ('fromIntegral' . age '>$<' 'param' ('nonNullable' 'int8'))
--
-- genderValue :: 'Value.Value' Gender
-- genderValue = 'enum' Nothing (Just "gender") genderText where
--   genderText gender = case gender of
--     Male -> "male"
--     Female -> "female"
-- @
data Params a = Params
  { forall a. Params a -> Int
size :: Int,
    -- | Serialization function, deferring the names of types that must be looked up at runtime.
    forall a.
Params a
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request :: ToBeResolved.ToBeResolved CodecsVocab.QualifiedTypeName CodecsVocab.TypeInfo (a -> [Maybe ByteString]),
    -- | Type shape for each parameter.
    forall a. Params a -> DList TypeShape
columnsMetadata :: DList TypeShape,
    forall a. Params a -> a -> DList Text
printer :: a -> DList Text
  }

instance Contravariant Params where
  contramap :: forall a' a. (a' -> a) -> Params a -> Params a'
contramap a' -> a
fn (Params Int
size ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request DList TypeShape
columnsMetadata a -> DList Text
printer) =
    Int
-> ToBeResolved
     QualifiedTypeName TypeInfo (a' -> [Maybe ByteString])
-> DList TypeShape
-> (a' -> DList Text)
-> Params a'
forall a.
Int
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
-> DList TypeShape
-> (a -> DList Text)
-> Params a
Params Int
size (((a -> [Maybe ByteString]) -> a' -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a' -> [Maybe ByteString])
forall a b.
(a -> b)
-> ToBeResolved QualifiedTypeName TypeInfo a
-> ToBeResolved QualifiedTypeName TypeInfo b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> [Maybe ByteString]) -> (a' -> a) -> a' -> [Maybe ByteString]
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
fn) ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request) DList TypeShape
columnsMetadata (a -> DList Text
printer (a -> DList Text) -> (a' -> a) -> a' -> DList Text
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
fn)

instance Divisible Params where
  divide :: forall a b c. (a -> (b, c)) -> Params b -> Params c -> Params a
divide
    a -> (b, c)
divisor
    (Params Int
leftSize ToBeResolved QualifiedTypeName TypeInfo (b -> [Maybe ByteString])
leftRequest DList TypeShape
leftColumnsMetadata b -> DList Text
leftPrinter)
    (Params Int
rightSize ToBeResolved QualifiedTypeName TypeInfo (c -> [Maybe ByteString])
rightRequest DList TypeShape
rightColumnsMetadata c -> DList Text
rightPrinter) =
      Params
        { size :: Int
size = Int
leftSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rightSize,
          request :: ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request =
            ((b -> [Maybe ByteString])
 -> (c -> [Maybe ByteString]) -> a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (b -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (c -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
forall a b c.
(a -> b -> c)
-> ToBeResolved QualifiedTypeName TypeInfo a
-> ToBeResolved QualifiedTypeName TypeInfo b
-> ToBeResolved QualifiedTypeName TypeInfo c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
              ( \b -> [Maybe ByteString]
leftSerializer c -> [Maybe ByteString]
rightSerializer a
input -> case a -> (b, c)
divisor a
input of
                  (b
leftInput, c
rightInput) -> b -> [Maybe ByteString]
leftSerializer b
leftInput [Maybe ByteString] -> [Maybe ByteString] -> [Maybe ByteString]
forall a. Semigroup a => a -> a -> a
<> c -> [Maybe ByteString]
rightSerializer c
rightInput
              )
              ToBeResolved QualifiedTypeName TypeInfo (b -> [Maybe ByteString])
leftRequest
              ToBeResolved QualifiedTypeName TypeInfo (c -> [Maybe ByteString])
rightRequest,
          columnsMetadata :: DList TypeShape
columnsMetadata = DList TypeShape
leftColumnsMetadata DList TypeShape -> DList TypeShape -> DList TypeShape
forall a. Semigroup a => a -> a -> a
<> DList TypeShape
rightColumnsMetadata,
          printer :: a -> DList Text
printer = \a
input -> case a -> (b, c)
divisor a
input of
            (b
leftInput, c
rightInput) -> b -> DList Text
leftPrinter b
leftInput DList Text -> DList Text -> DList Text
forall a. Semigroup a => a -> a -> a
<> c -> DList Text
rightPrinter c
rightInput
        }
  conquer :: forall a. Params a
conquer =
    Params
      { size :: Int
size = Int
0,
        request :: ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request = (a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
forall a. a -> ToBeResolved QualifiedTypeName TypeInfo a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a -> [Maybe ByteString]
forall a. Monoid a => a
mempty,
        columnsMetadata :: DList TypeShape
columnsMetadata = DList TypeShape
forall a. Monoid a => a
mempty,
        printer :: a -> DList Text
printer = a -> DList Text
forall a. Monoid a => a
mempty
      }

instance Semigroup (Params a) where
  Params Int
leftSize ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
leftRequest DList TypeShape
leftColumnsMetadata a -> DList Text
leftPrinter <> :: Params a -> Params a -> Params a
<> Params Int
rightSize ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
rightRequest DList TypeShape
rightColumnsMetadata a -> DList Text
rightPrinter =
    Params
      { size :: Int
size = Int
leftSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rightSize,
        request :: ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request = ((a -> [Maybe ByteString])
 -> (a -> [Maybe ByteString]) -> a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
forall a b c.
(a -> b -> c)
-> ToBeResolved QualifiedTypeName TypeInfo a
-> ToBeResolved QualifiedTypeName TypeInfo b
-> ToBeResolved QualifiedTypeName TypeInfo c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\a -> [Maybe ByteString]
leftSerializer a -> [Maybe ByteString]
rightSerializer a
input -> a -> [Maybe ByteString]
leftSerializer a
input [Maybe ByteString] -> [Maybe ByteString] -> [Maybe ByteString]
forall a. Semigroup a => a -> a -> a
<> a -> [Maybe ByteString]
rightSerializer a
input) ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
leftRequest ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
rightRequest,
        columnsMetadata :: DList TypeShape
columnsMetadata = DList TypeShape
leftColumnsMetadata DList TypeShape -> DList TypeShape -> DList TypeShape
forall a. Semigroup a => a -> a -> a
<> DList TypeShape
rightColumnsMetadata,
        printer :: a -> DList Text
printer = \a
input -> a -> DList Text
leftPrinter a
input DList Text -> DList Text -> DList Text
forall a. Semigroup a => a -> a -> a
<> a -> DList Text
rightPrinter a
input
      }

instance Monoid (Params a) where
  mempty :: Params a
mempty = Params a
forall a. Params a
forall (f :: * -> *) a. Divisible f => f a
conquer

value :: Value.Value a -> Params a
value :: forall a. Value a -> Params a
value (Value.Value Maybe Text
schemaName Text
typeName Maybe Word32
scalarOid Maybe Word32
arrayOid Word
dimensionality Bool
textFormat ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize a -> TextBuilder
print) =
  let staticOid :: Maybe Word32
staticOid = if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Maybe Word32
scalarOid else Maybe Word32
arrayOid
      toRequest :: f (a -> Encoding) -> f (a -> f (Maybe ByteString))
toRequest = ((a -> Encoding) -> a -> f (Maybe ByteString))
-> f (a -> Encoding) -> f (a -> f (Maybe ByteString))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a -> Encoding
encode -> Maybe ByteString -> f (Maybe ByteString)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe ByteString -> f (Maybe ByteString))
-> (a -> Maybe ByteString) -> a -> f (Maybe ByteString)
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
. ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> (a -> ByteString) -> a -> Maybe ByteString
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
. Encoding -> ByteString
Binary.encodingBytes (Encoding -> ByteString) -> (a -> Encoding) -> a -> ByteString
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 -> Encoding
encode)
      printer :: a -> DList Text
printer = Text -> DList Text
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> DList Text) -> (a -> Text) -> a -> DList Text
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
. TextBuilder -> Text
TextBuilder.toText (TextBuilder -> Text) -> (a -> TextBuilder) -> a -> Text
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 -> TextBuilder
print
      size :: a
size = a
1
   in case Maybe Word32
staticOid of
        Just Word32
oid ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              request :: ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request = ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
forall {f :: * -> *} {f :: * -> *} {a}.
(Applicative f, Functor f) =>
f (a -> Encoding) -> f (a -> f (Maybe ByteString))
toRequest ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize,
              columnsMetadata :: DList TypeShape
columnsMetadata = TypeShape -> DList TypeShape
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TypeRef -> Word -> Bool -> TypeShape
TypeShape (Word32 -> TypeRef
CodecsVocab.TypeRef.KnownOid Word32
oid) Word
dimensionality Bool
textFormat),
              a -> DList Text
printer :: a -> DList Text
printer :: a -> DList Text
printer
            }
        Maybe Word32
Nothing ->
          let key :: QualifiedTypeName
key = Maybe Text -> Text -> QualifiedTypeName
CodecsVocab.QualifiedTypeName.QualifiedTypeName Maybe Text
schemaName Text
typeName
           in Params
                { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
                  request :: ToBeResolved QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
request = ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved
     QualifiedTypeName TypeInfo (a -> [Maybe ByteString])
forall {f :: * -> *} {f :: * -> *} {a}.
(Applicative f, Functor f) =>
f (a -> Encoding) -> f (a -> f (Maybe ByteString))
toRequest (QualifiedTypeName
-> ToBeResolved QualifiedTypeName TypeInfo TypeInfo
forall k v. k -> ToBeResolved k v v
ToBeResolved.lookup QualifiedTypeName
key ToBeResolved QualifiedTypeName TypeInfo TypeInfo
-> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
forall a b.
ToBeResolved QualifiedTypeName TypeInfo a
-> ToBeResolved QualifiedTypeName TypeInfo b
-> ToBeResolved QualifiedTypeName TypeInfo b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize),
                  columnsMetadata :: DList TypeShape
columnsMetadata = TypeShape -> DList TypeShape
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TypeRef -> Word -> Bool -> TypeShape
TypeShape (QualifiedTypeName -> TypeRef
CodecsVocab.TypeRef.NamedType QualifiedTypeName
key) Word
dimensionality Bool
textFormat),
                  a -> DList Text
printer :: a -> DList Text
printer :: a -> DList Text
printer
                }

nullableValue :: Value.Value a -> Params (Maybe a)
nullableValue :: forall a. Value a -> Params (Maybe a)
nullableValue (Value.Value Maybe Text
schemaName Text
typeName Maybe Word32
scalarOid Maybe Word32
arrayOid Word
dimensionality Bool
textFormat ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize a -> TextBuilder
print) =
  let staticOid :: Maybe Word32
staticOid = if Word
dimensionality Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0 then Maybe Word32
scalarOid else Maybe Word32
arrayOid
      toRequest :: f (a -> Encoding) -> f (f a -> f (f ByteString))
toRequest = ((a -> Encoding) -> f a -> f (f ByteString))
-> f (a -> Encoding) -> f (f a -> f (f ByteString))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a -> Encoding
encode -> f ByteString -> f (f ByteString)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (f ByteString -> f (f ByteString))
-> (f a -> f ByteString) -> f a -> f (f ByteString)
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 -> ByteString) -> f a -> f ByteString
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Encoding -> ByteString
Binary.encodingBytes (Encoding -> ByteString) -> (a -> Encoding) -> a -> ByteString
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 -> Encoding
encode))
      printer :: Maybe a -> DList Text
printer = Text -> DList Text
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> DList Text) -> (Maybe a -> Text) -> Maybe a -> DList Text
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
. Text -> (a -> Text) -> Maybe a -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"null" (TextBuilder -> Text
TextBuilder.toText (TextBuilder -> Text) -> (a -> TextBuilder) -> a -> Text
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 -> TextBuilder
print)
      size :: a
size = a
1
   in case Maybe Word32
staticOid of
        Just Word32
oid ->
          Params
            { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
              request :: ToBeResolved
  QualifiedTypeName TypeInfo (Maybe a -> [Maybe ByteString])
request = ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved
     QualifiedTypeName TypeInfo (Maybe a -> [Maybe ByteString])
forall {f :: * -> *} {f :: * -> *} {f :: * -> *} {a}.
(Applicative f, Functor f, Functor f) =>
f (a -> Encoding) -> f (f a -> f (f ByteString))
toRequest ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize,
              columnsMetadata :: DList TypeShape
columnsMetadata = TypeShape -> DList TypeShape
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TypeRef -> Word -> Bool -> TypeShape
TypeShape (Word32 -> TypeRef
CodecsVocab.TypeRef.KnownOid Word32
oid) Word
dimensionality Bool
textFormat),
              Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer
            }
        Maybe Word32
Nothing ->
          let key :: QualifiedTypeName
key = Maybe Text -> Text -> QualifiedTypeName
CodecsVocab.QualifiedTypeName.QualifiedTypeName Maybe Text
schemaName Text
typeName
           in Params
                { Int
forall {a}. Num a => a
size :: Int
size :: forall {a}. Num a => a
size,
                  request :: ToBeResolved
  QualifiedTypeName TypeInfo (Maybe a -> [Maybe ByteString])
request = ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved
     QualifiedTypeName TypeInfo (Maybe a -> [Maybe ByteString])
forall {f :: * -> *} {f :: * -> *} {f :: * -> *} {a}.
(Applicative f, Functor f, Functor f) =>
f (a -> Encoding) -> f (f a -> f (f ByteString))
toRequest (QualifiedTypeName
-> ToBeResolved QualifiedTypeName TypeInfo TypeInfo
forall k v. k -> ToBeResolved k v v
ToBeResolved.lookup QualifiedTypeName
key ToBeResolved QualifiedTypeName TypeInfo TypeInfo
-> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
-> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
forall a b.
ToBeResolved QualifiedTypeName TypeInfo a
-> ToBeResolved QualifiedTypeName TypeInfo b
-> ToBeResolved QualifiedTypeName TypeInfo b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ToBeResolved QualifiedTypeName TypeInfo (a -> Encoding)
serialize),
                  columnsMetadata :: DList TypeShape
columnsMetadata = TypeShape -> DList TypeShape
forall a. a -> DList a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TypeRef -> Word -> Bool -> TypeShape
TypeShape (QualifiedTypeName -> TypeRef
CodecsVocab.TypeRef.NamedType QualifiedTypeName
key) Word
dimensionality Bool
textFormat),
                  Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer :: Maybe a -> DList Text
printer
                }

-- |
-- No parameters. Same as `mempty` and `conquered`.
noParams :: Params ()
noParams :: Params ()
noParams = Params ()
forall a. Monoid a => a
mempty

-- |
-- Lift a single parameter encoder, with its nullability specified,
-- associating it with a single placeholder.
param :: NullableOrNot.NullableOrNot Value.Value a -> Params a
param :: forall a. NullableOrNot Value a -> Params a
param = \case
  NullableOrNot.NonNullable Value a
valueEnc -> Value a -> Params a
forall a. Value a -> Params a
value Value a
valueEnc
  NullableOrNot.Nullable Value a1
valueEnc -> Value a1 -> Params (Maybe a1)
forall a. Value a -> Params (Maybe a)
nullableValue Value a1
valueEnc