packages feed

grpc-spec-1.0.0: src/Network/GRPC/Spec/Util/Protobuf.hs

-- | Protobuf utilities
--
-- Intended for qualified import.
--
-- > import Network.GRPC.Spec.Util.Protobuf qualified as Protobuf
module Network.GRPC.Spec.Util.Protobuf (
    -- * Serialization
    parseStrict
  , parseLazy
  , buildStrict
  , buildLazy
  ) where

import Data.Binary.Builder qualified as Builder
import Data.ByteString qualified as Strict (ByteString)
import Data.ByteString.Lazy qualified as BS.Lazy
import Data.ByteString.Lazy qualified as Lazy (ByteString)
import Data.ProtoLens (Message)
import Data.ProtoLens qualified as Protobuf
import Data.ProtoLens.Encoding.Parser (Parser)
import Data.ProtoLens.Encoding.Parser qualified as Protobuf
import Data.Proxy
import Data.Text qualified as Text

{-------------------------------------------------------------------------------
  Serialization
-------------------------------------------------------------------------------}

parseStrict :: Message msg => Strict.ByteString -> Either String msg
parseStrict = Protobuf.runParser parseMessage

-- | Parse lazy bytestring
--
-- TODO: <https://github.com/well-typed/grapesy/issues/119>.
-- We currently turn this into a strict bytestring before parsing.
parseLazy :: Message msg => Lazy.ByteString -> Either String msg
parseLazy = parseStrict . BS.Lazy.toStrict

buildStrict :: Message msg => msg -> Strict.ByteString
buildStrict = BS.Lazy.toStrict . buildLazy

buildLazy :: Message msg => msg -> Lazy.ByteString
buildLazy = Builder.toLazyByteString . Protobuf.buildMessage

{-------------------------------------------------------------------------------
  Internal auxilairy
-------------------------------------------------------------------------------}

parseMessage :: forall msg. Protobuf.Message msg => Parser msg
parseMessage = do
    msg   <- Protobuf.parseMessage
    atEnd <- Protobuf.atEnd
    if atEnd then
      return msg
    else
      fail $ concat [
          Text.unpack $ Protobuf.messageName $ Proxy @msg
        , ": unconsumed bytes"
        ]