-- | Convenience functions for working with binary RPC
--
-- Intended for qualified import.
--
-- import Network.GRPC.Server.Binary qualified as Binary
module Network.GRPC.Server.Binary (
    -- | Convenience wrappers using @binary@ for serialization/deserialization
    sendOutput
  , sendNextOutput
  , sendFinalOutput
  , recvInput
  , recvNextInput
  , recvFinalInput
  ) where

import Data.Binary
import Data.ByteString.Lazy qualified as Lazy (ByteString)
import GHC.Stack

import Network.GRPC.Common
import Network.GRPC.Common.Binary (decodeOrThrow)
import Network.GRPC.Server (Call)
import Network.GRPC.Server qualified as Server

{-------------------------------------------------------------------------------
  Convenience wrapers using @binary@ for serialization/deserialization
-------------------------------------------------------------------------------}

sendOutput ::
     (Binary out, Output rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> StreamElem (ResponseTrailingMetadata rpc) out
  -> IO ()
sendOutput :: forall {k} out (rpc :: k).
(Binary out, Output rpc ~ ByteString, HasCallStack) =>
Call rpc -> StreamElem (ResponseTrailingMetadata rpc) out -> IO ()
sendOutput Call rpc
call StreamElem (ResponseTrailingMetadata rpc) out
out =
    Call rpc
-> StreamElem (ResponseTrailingMetadata rpc) (Output rpc) -> IO ()
forall {k} (rpc :: k).
HasCallStack =>
Call rpc
-> StreamElem (ResponseTrailingMetadata rpc) (Output rpc) -> IO ()
Server.sendOutput Call rpc
call (out -> ByteString
forall a. Binary a => a -> ByteString
encode (out -> ByteString)
-> StreamElem (ResponseTrailingMetadata rpc) out
-> StreamElem (ResponseTrailingMetadata rpc) ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StreamElem (ResponseTrailingMetadata rpc) out
out)

sendNextOutput ::
     (Binary out, Output rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> out
  -> IO ()
sendNextOutput :: forall {k} out (rpc :: k).
(Binary out, Output rpc ~ ByteString, HasCallStack) =>
Call rpc -> out -> IO ()
sendNextOutput Call rpc
call out
out =
    Call rpc -> Output rpc -> IO ()
forall {k} (rpc :: k).
HasCallStack =>
Call rpc -> Output rpc -> IO ()
Server.sendNextOutput Call rpc
call (out -> ByteString
forall a. Binary a => a -> ByteString
encode out
out)

sendFinalOutput ::
     (Binary out, Output rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> (out, ResponseTrailingMetadata rpc)
  -> IO ()
sendFinalOutput :: forall {k} out (rpc :: k).
(Binary out, Output rpc ~ ByteString, HasCallStack) =>
Call rpc -> (out, ResponseTrailingMetadata rpc) -> IO ()
sendFinalOutput Call rpc
call (out
out, ResponseTrailingMetadata rpc
trailers) =
    Call rpc -> (Output rpc, ResponseTrailingMetadata rpc) -> IO ()
forall {k} (rpc :: k).
HasCallStack =>
Call rpc -> (Output rpc, ResponseTrailingMetadata rpc) -> IO ()
Server.sendFinalOutput Call rpc
call (out -> ByteString
forall a. Binary a => a -> ByteString
encode out
out, ResponseTrailingMetadata rpc
trailers)

recvInput ::
     (Binary inp, Input rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> IO (StreamElem NoMetadata inp)
recvInput :: forall {k} inp (rpc :: k).
(Binary inp, Input rpc ~ ByteString, HasCallStack) =>
Call rpc -> IO (StreamElem NoMetadata inp)
recvInput Call rpc
call =
    Call rpc -> IO (StreamElem NoMetadata (Input rpc))
forall {k} (rpc :: k).
HasCallStack =>
Call rpc -> IO (StreamElem NoMetadata (Input rpc))
Server.recvInput Call rpc
call IO (StreamElem NoMetadata ByteString)
-> (StreamElem NoMetadata ByteString
    -> IO (StreamElem NoMetadata inp))
-> IO (StreamElem NoMetadata inp)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ByteString -> IO inp)
-> StreamElem NoMetadata ByteString
-> IO (StreamElem NoMetadata inp)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> StreamElem NoMetadata a -> f (StreamElem NoMetadata b)
traverse ByteString -> IO inp
forall (m :: * -> *) a. (MonadIO m, Binary a) => ByteString -> m a
decodeOrThrow

recvNextInput ::
     (Binary inp, Input rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> IO inp
recvNextInput :: forall {k} inp (rpc :: k).
(Binary inp, Input rpc ~ ByteString, HasCallStack) =>
Call rpc -> IO inp
recvNextInput Call rpc
call =
    Call rpc -> IO (Input rpc)
forall {k} (rpc :: k). HasCallStack => Call rpc -> IO (Input rpc)
Server.recvNextInput Call rpc
call IO ByteString -> (ByteString -> IO inp) -> IO inp
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IO inp
forall (m :: * -> *) a. (MonadIO m, Binary a) => ByteString -> m a
decodeOrThrow

recvFinalInput ::
     (Binary inp, Input rpc ~ Lazy.ByteString, HasCallStack)
  => Call rpc
  -> IO inp
recvFinalInput :: forall {k} inp (rpc :: k).
(Binary inp, Input rpc ~ ByteString, HasCallStack) =>
Call rpc -> IO inp
recvFinalInput Call rpc
call =
     Call rpc -> IO (Input rpc)
forall {k} (rpc :: k). HasCallStack => Call rpc -> IO (Input rpc)
Server.recvFinalInput Call rpc
call IO ByteString -> (ByteString -> IO inp) -> IO inp
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> IO inp
forall (m :: * -> *) a. (MonadIO m, Binary a) => ByteString -> m a
decodeOrThrow