module Twirp
  ( Protobuf
  , module Middleware
  ) where

import Twirp.Middleware.Errors as Middleware

import Data.Bifunctor (first)
import Data.ByteString.Lazy.Char8 as BC
import Data.ByteString.Builder as BB
import Network.HTTP.Media ((//))
import Data.ProtoLens.Encoding as Proto
import Data.ProtoLens.Message (Message)
import Servant.API

data Protobuf

instance Accept Protobuf where
  contentType :: Proxy Protobuf -> MediaType
contentType Proxy Protobuf
_ = ByteString
"application" ByteString -> ByteString -> MediaType
// ByteString
"protobuf"

instance Message a => MimeRender Protobuf a where
  mimeRender :: Proxy Protobuf -> a -> ByteString
mimeRender Proxy Protobuf
_ = Builder -> ByteString
BB.toLazyByteString (Builder -> ByteString) -> (a -> Builder) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder
forall msg. Message msg => msg -> Builder
Proto.buildMessage

instance Message a => MimeUnrender Protobuf a where
  mimeUnrender :: Proxy Protobuf -> ByteString -> Either String a
mimeUnrender Proxy Protobuf
_ = (String -> String) -> Either String a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> String
forall a. Show a => a -> String
show (Either String a -> Either String a)
-> (ByteString -> Either String a) -> ByteString -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String a
forall msg. Message msg => ByteString -> Either String msg
Proto.decodeMessage (ByteString -> Either String a)
-> (ByteString -> ByteString) -> ByteString -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BC.toStrict