{-# language DataKinds             #-}
{-# language FlexibleContexts      #-}
{-# language FlexibleInstances     #-}
{-# language MultiParamTypeClasses #-}
{-# language PolyKinds             #-}
{-# language TypeFamilies          #-}
{-# language UndecidableInstances  #-}
{-|
Description : Supported serialization formats for gRPC

Currently Protocol Buffers and Avro can be used as
serialization format for the messages in gRPC
requests and replies. This module provides types
and proxies used in both @mu-grpc-client@ and
@mu-grpc-server@ to drive this choice of serialization.
-}
module Mu.GRpc.Bridge where

import           Data.ByteString
import           Data.Kind
import           Data.Proxy
import           Network.GRPC.HTTP2.Proto3Wire

import           Mu.GRpc.Avro

-- | Serialization formats supported with gRPC.
data GRpcMessageProtocol
  = MsgProtoBuf  -- ^ Protocol Buffers.
  | MsgAvro      -- ^ Avro.
  deriving (GRpcMessageProtocol -> GRpcMessageProtocol -> Bool
(GRpcMessageProtocol -> GRpcMessageProtocol -> Bool)
-> (GRpcMessageProtocol -> GRpcMessageProtocol -> Bool)
-> Eq GRpcMessageProtocol
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GRpcMessageProtocol -> GRpcMessageProtocol -> Bool
$c/= :: GRpcMessageProtocol -> GRpcMessageProtocol -> Bool
== :: GRpcMessageProtocol -> GRpcMessageProtocol -> Bool
$c== :: GRpcMessageProtocol -> GRpcMessageProtocol -> Bool
Eq, Int -> GRpcMessageProtocol -> ShowS
[GRpcMessageProtocol] -> ShowS
GRpcMessageProtocol -> String
(Int -> GRpcMessageProtocol -> ShowS)
-> (GRpcMessageProtocol -> String)
-> ([GRpcMessageProtocol] -> ShowS)
-> Show GRpcMessageProtocol
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GRpcMessageProtocol] -> ShowS
$cshowList :: [GRpcMessageProtocol] -> ShowS
show :: GRpcMessageProtocol -> String
$cshow :: GRpcMessageProtocol -> String
showsPrec :: Int -> GRpcMessageProtocol -> ShowS
$cshowsPrec :: Int -> GRpcMessageProtocol -> ShowS
Show)

-- | Choose Protocol Buffers as serialization format for gRPC.
--   This value is commonly used to create a client or server.
msgProtoBuf :: Proxy 'MsgProtoBuf
msgProtoBuf :: Proxy 'MsgProtoBuf
msgProtoBuf = Proxy 'MsgProtoBuf
forall k (t :: k). Proxy t
Proxy
-- | Choose Avro as serialization format for gRPC.
--   This value is commonly used to create a client or server.
msgAvro :: Proxy 'MsgAvro
msgAvro :: Proxy 'MsgAvro
msgAvro = Proxy 'MsgAvro
forall k (t :: k). Proxy t
Proxy

-- | Defines how to build serialization-specific
--   RPC locators from a triple of (package, server, method).
class MkRPC (p :: GRpcMessageProtocol) where
  type RPCTy p :: Type
  mkRPC :: Proxy p -> ByteString -> ByteString -> ByteString -> RPCTy p
instance MkRPC 'MsgProtoBuf where
  type RPCTy 'MsgProtoBuf = RPC
  mkRPC :: Proxy 'MsgProtoBuf
-> ByteString -> ByteString -> ByteString -> RPCTy 'MsgProtoBuf
mkRPC Proxy 'MsgProtoBuf
_ = ByteString -> ByteString -> ByteString -> RPC
ByteString -> ByteString -> ByteString -> RPCTy 'MsgProtoBuf
RPC
instance MkRPC 'MsgAvro where
  type RPCTy 'MsgAvro = AvroRPC
  mkRPC :: Proxy 'MsgAvro
-> ByteString -> ByteString -> ByteString -> RPCTy 'MsgAvro
mkRPC Proxy 'MsgAvro
_ = ByteString -> ByteString -> ByteString -> AvroRPC
ByteString -> ByteString -> ByteString -> RPCTy 'MsgAvro
AvroRPC