{-# LANGUAGE BangPatterns, FlexibleContexts, ScopedTypeVariables #-}
module Text.ProtocolBuffers.TextMessage (
-- * User API functions
-- ** Main encoding and decoding operations
        messagePutText,
        messageGetText,
-- * Internal API functions
        TextMsg(..),
        TextType(..),
        tellShow,
        tellSubMessage,
        getRead,
        getSubMessage,
    ) where

import Control.Monad.Identity (Identity)
import Control.Monad (void)
import Control.Monad.Writer (Writer, execWriter, tell, censor)
import Data.Char
import Data.Foldable (toList)
import Data.Int
import Data.List (intercalate)
import Data.Sequence (singleton)
import Data.Traversable
import Data.Word
import Text.Parsec
import Text.Printf
import Text.ProtocolBuffers.Basic
import Text.Read

import qualified Data.ByteString.Lazy.Char8 as C8
import qualified Data.ByteString.Lazy.UTF8 as U8
import qualified Text.Parsec.Token as T

type Log = Seq (Int, String)
type Output = Writer Log ()

-- | Printable and readable messages
class TextMsg a where
    textPut :: a -> Output
    textGet :: Stream s Identity Char => Parsec s () a

-- | Printable and readable field types
class TextType a where
    tellT :: String -> a -> Output
    getT :: Stream s Identity Char => String -> Parsec s () a

tells :: String -> Output
tells :: String -> Output
tells s :: String
s = Seq (Int, String) -> Output
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell (Seq (Int, String) -> Output) -> Seq (Int, String) -> Output
forall a b. (a -> b) -> a -> b
$ (Int, String) -> Seq (Int, String)
forall a. a -> Seq a
singleton (0, String
s)

tellShow :: Show a => String -> a -> Output
tellShow :: String -> a -> Output
tellShow name :: String
name v :: a
v = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
v

tellStr :: String -> ByteString -> Output
tellStr :: String -> ByteString -> Output
tellStr name :: String
name s :: ByteString
s = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
dumpDecimal ByteString
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\""

tellSubMessage :: TextMsg a => String -> a -> Output
tellSubMessage :: String -> a -> Output
tellSubMessage name :: String
name m :: a
m = do
    String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ " {"
    Output -> Output
forall a.
WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
indent (Output -> Output) -> Output -> Output
forall a b. (a -> b) -> a -> b
$ a -> Output
forall a. TextMsg a => a -> Output
textPut a
m
    String -> Output
tells "}"
    where
    indent :: WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
indent = (Seq (Int, String) -> Seq (Int, String))
-> WriterT (Seq (Int, String)) Identity a
-> WriterT (Seq (Int, String)) Identity a
forall w (m :: * -> *) a. MonadWriter w m => (w -> w) -> m a -> m a
censor (((Int, String) -> (Int, String))
-> Seq (Int, String) -> Seq (Int, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(!Int
n, s :: String
s) -> (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1, String
s)))

dumpDecimal :: ByteString -> String
dumpDecimal :: ByteString -> String
dumpDecimal = (Char -> String -> String) -> String -> ByteString -> String
forall a. (Char -> a -> a) -> a -> ByteString -> a
C8.foldr Char -> String -> String
escape []
    where
    escape :: Char -> String -> String
escape '\n' str :: String
str = "\\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
    escape '\"' str :: String
str = "\\\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str
    escape c :: Char
c str :: String
str | Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& Char -> Bool
isPrint Char
c = Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
str
    escape c :: Char
c str :: String
str = String -> Char -> String
forall r. PrintfType r => String -> r
printf "\\%03d" Char
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
str

instance TextType Int32 where
    tellT :: String -> Int32 -> Output
tellT = String -> Int32 -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Int32
getT = Parsec s () Int32 -> String -> Parsec s () Int32
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Int32
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
integer

instance TextType Int64 where
    tellT :: String -> Int64 -> Output
tellT = String -> Int64 -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Int64
getT = Parsec s () Int64 -> String -> Parsec s () Int64
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Int64
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
integer

instance TextType Word32 where
    tellT :: String -> Word32 -> Output
tellT = String -> Word32 -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Word32
getT = Parsec s () Word32 -> String -> Parsec s () Word32
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Word32
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
natural

instance TextType Word64 where
    tellT :: String -> Word64 -> Output
tellT = String -> Word64 -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Word64
getT = Parsec s () Word64 -> String -> Parsec s () Word64
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Word64
forall a s. (Integral a, Stream s Identity Char) => Parsec s () a
natural

instance TextType Bool where
    tellT :: String -> Bool -> Output
tellT name :: String
name True = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": true"
    tellT name :: String
name False = String -> Output
tells (String -> Output) -> String -> Output
forall a b. (a -> b) -> a -> b
$ String
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": false"
    getT :: String -> Parsec s () Bool
getT name :: String
name = do
        String
v <- Parsec s () String -> String -> Parsec s () String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar (String -> Parsec s () String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "true" Parsec s () String -> Parsec s () String -> Parsec s () String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> Parsec s () String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "false") String
name
        Bool -> Parsec s () Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (String
v String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "true")

instance TextType Double where
    tellT :: String -> Double -> Output
tellT = String -> Double -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Double
getT = Parsec s () Double -> String -> Parsec s () Double
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar Parsec s () Double
forall s. Stream s Identity Char => Parsec s () Double
float

instance TextType Float where
    tellT :: String -> Float -> Output
tellT = String -> Float -> Output
forall a. Show a => String -> a -> Output
tellShow
    getT :: String -> Parsec s () Float
getT name :: String
name = Double -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> Float)
-> ParsecT s () Identity Double -> Parsec s () Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity Double
-> String -> ParsecT s () Identity Double
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity Double
forall s. Stream s Identity Char => Parsec s () Double
float String
name

instance TextType Utf8 where
    tellT :: String -> Utf8 -> Output
tellT name :: String
name (Utf8 s :: ByteString
s) = String -> ByteString -> Output
tellStr String
name ByteString
s
    getT :: String -> Parsec s () Utf8
getT name :: String
name = String -> Utf8
uFromString (String -> Utf8)
-> ParsecT s () Identity String -> Parsec s () Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity String
-> String -> ParsecT s () Identity String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity String
forall s. Stream s Identity Char => Parsec s () String
stringLiteral String
name

instance TextType ByteString where
    tellT :: String -> ByteString -> Output
tellT = String -> ByteString -> Output
tellStr
    getT :: String -> Parsec s () ByteString
getT name :: String
name = String -> ByteString
U8.fromString (String -> ByteString)
-> ParsecT s () Identity String -> Parsec s () ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s () Identity String
-> String -> ParsecT s () Identity String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar ParsecT s () Identity String
forall s. Stream s Identity Char => Parsec s () String
stringLiteral String
name

instance TextType a => TextType (Maybe a) where
    tellT :: String -> Maybe a -> Output
tellT _ Nothing = () -> Output
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    tellT name :: String
name (Just v :: a
v) = String -> a -> Output
forall a. TextType a => String -> a -> Output
tellT String
name a
v
    getT :: String -> Parsec s () (Maybe a)
getT name :: String
name = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> ParsecT s () Identity a -> Parsec s () (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT s () Identity a
forall a s.
(TextType a, Stream s Identity Char) =>
String -> Parsec s () a
getT String
name

instance TextType a => TextType (Seq a) where
    tellT :: String -> Seq a -> Output
tellT name :: String
name xs :: Seq a
xs = WriterT (Seq (Int, String)) Identity (Seq ()) -> Output
forall (f :: * -> *) a. Functor f => f a -> f ()
void (WriterT (Seq (Int, String)) Identity (Seq ()) -> Output)
-> WriterT (Seq (Int, String)) Identity (Seq ()) -> Output
forall a b. (a -> b) -> a -> b
$ Seq a
-> (a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ())
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM Seq a
xs ((a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ()))
-> (a -> Output) -> WriterT (Seq (Int, String)) Identity (Seq ())
forall a b. (a -> b) -> a -> b
$ String -> a -> Output
forall a. TextType a => String -> a -> Output
tellT String
name
    getT :: String -> Parsec s () (Seq a)
getT = String -> String -> Parsec s () (Seq a)
forall a. HasCallStack => String -> a
error "should not take sequence directly"

-- | This writes message as text-format protobuf to 'String'
messagePutText :: TextMsg a => a -> String
messagePutText :: a -> String
messagePutText = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "\n" ([String] -> String) -> (a -> [String]) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seq String -> [String]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Seq String -> [String]) -> (a -> Seq String) -> a -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, String) -> String) -> Seq (Int, String) -> Seq String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int, String) -> String
setIndent (Seq (Int, String) -> Seq String)
-> (a -> Seq (Int, String)) -> a -> Seq String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Output -> Seq (Int, String)
forall w a. Writer w a -> w
execWriter (Output -> Seq (Int, String))
-> (a -> Output) -> a -> Seq (Int, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Output
forall a. TextMsg a => a -> Output
textPut
    where
    setIndent :: (Int, String) -> String
setIndent (n :: Int
n, s :: String
s) = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* 2) ' ' String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s

lexer :: Stream s Identity Char => T.GenTokenParser s () Identity
lexer :: GenTokenParser s () Identity
lexer = GenLanguageDef s () Identity -> GenTokenParser s () Identity
forall s (m :: * -> *) u.
Stream s m Char =>
GenLanguageDef s u m -> GenTokenParser s u m
T.makeTokenParser LanguageDef :: forall s u (m :: * -> *).
String
-> String
-> String
-> Bool
-> ParsecT s u m Char
-> ParsecT s u m Char
-> ParsecT s u m Char
-> ParsecT s u m Char
-> [String]
-> [String]
-> Bool
-> GenLanguageDef s u m
T.LanguageDef {
            identStart :: ParsecT s () Identity Char
T.identStart     = ParsecT s () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter ParsecT s () Identity Char
-> ParsecT s () Identity Char -> ParsecT s () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '_'
          , identLetter :: ParsecT s () Identity Char
T.identLetter    = ParsecT s () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum ParsecT s () Identity Char
-> ParsecT s () Identity Char -> ParsecT s () Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '_'
          , opStart :: ParsecT s () Identity Char
T.opStart        = String -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf ":!#$%&*+./<=>?@\\^|-~"
          , opLetter :: ParsecT s () Identity Char
T.opLetter       = String -> ParsecT s () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf ":!#$%&*+./<=>?@\\^|-~"
          , caseSensitive :: Bool
T.caseSensitive  = Bool
True
          , commentStart :: String
T.commentStart   = "/*"
          , commentEnd :: String
T.commentEnd     = "*/"
          , commentLine :: String
T.commentLine    = "//"
          , nestedComments :: Bool
T.nestedComments = Bool
True
          , reservedNames :: [String]
T.reservedNames  = []
          , reservedOpNames :: [String]
T.reservedOpNames= []
    }

symbol :: Stream s Identity Char => String -> Parsec s () ()
symbol :: String -> Parsec s () ()
symbol sym :: String
sym = ParsecT s () Identity String -> Parsec s () ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT s () Identity String -> Parsec s () ())
-> ParsecT s () Identity String -> Parsec s () ()
forall a b. (a -> b) -> a -> b
$ GenTokenParser s () Identity
-> String -> ParsecT s () Identity String
forall s u (m :: * -> *).
GenTokenParser s u m -> String -> ParsecT s u m String
T.symbol GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer String
sym

colon :: Stream s Identity Char => Parsec s () ()
colon :: Parsec s () ()
colon = ParsecT s () Identity String -> Parsec s () ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (ParsecT s () Identity String -> Parsec s () ())
-> ParsecT s () Identity String -> Parsec s () ()
forall a b. (a -> b) -> a -> b
$ GenTokenParser s () Identity -> ParsecT s () Identity String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.colon GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

braces :: Stream s Identity Char => Parsec s () a -> Parsec s () a
braces :: Parsec s () a -> Parsec s () a
braces = GenTokenParser s () Identity
-> forall a. ParsecT s () Identity a -> ParsecT s () Identity a
forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
T.braces GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

natural :: (Integral a, Stream s Identity Char) => Parsec s () a
natural :: Parsec s () a
natural = Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> ParsecT s () Identity Integer -> Parsec s () a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity -> ParsecT s () Identity Integer
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
T.natural GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

integer :: (Integral a, Stream s Identity Char) => Parsec s () a
integer :: Parsec s () a
integer = Integer -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> a) -> ParsecT s () Identity Integer -> Parsec s () a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity -> ParsecT s () Identity Integer
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
T.integer GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

float :: Stream s Identity Char => Parsec s () Double
float :: Parsec s () Double
float = (Integer -> Double)
-> (Double -> Double) -> Either Integer Double -> Double
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Integer -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double -> Double
forall a. a -> a
id (Either Integer Double -> Double)
-> ParsecT s () Identity (Either Integer Double)
-> Parsec s () Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenTokenParser s () Identity
-> ParsecT s () Identity (Either Integer Double)
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m (Either Integer Double)
T.naturalOrFloat GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

stringLiteral :: Stream s Identity Char => Parsec s () String
stringLiteral :: Parsec s () String
stringLiteral = GenTokenParser s () Identity -> Parsec s () String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.stringLiteral GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer

getRead :: forall a s . (Read a, Stream s Identity Char) => String -> Parsec s () a
getRead :: String -> Parsec s () a
getRead name :: String
name = Parsec s () a -> Parsec s () a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Parsec s () a -> Parsec s () a) -> Parsec s () a -> Parsec s () a
forall a b. (a -> b) -> a -> b
$ do
    String
v <- Parsec s () String -> String -> Parsec s () String
forall s a.
Stream s Identity Char =>
Parsec s () a -> String -> Parsec s () a
getScalar (GenTokenParser s () Identity -> Parsec s () String
forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
T.identifier GenTokenParser s () Identity
forall s. Stream s Identity Char => GenTokenParser s () Identity
lexer) String
name
    case String -> Maybe a
forall a. Read a => String -> Maybe a
readMaybe String
v of
        Just r :: a
r -> a -> Parsec s () a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
        Nothing -> String -> Parsec s () a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parsec s () a) -> String -> Parsec s () a
forall a b. (a -> b) -> a -> b
$ "can't parse " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v

getScalar :: Stream s Identity Char => Parsec s () a -> String -> Parsec s () a
getScalar :: Parsec s () a -> String -> Parsec s () a
getScalar parser :: Parsec s () a
parser name :: String
name = String -> Parsec s () ()
forall s. Stream s Identity Char => String -> Parsec s () ()
symbol String
name Parsec s () () -> Parsec s () () -> Parsec s () ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () ()
forall s. Stream s Identity Char => Parsec s () ()
colon Parsec s () () -> Parsec s () a -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () a
parser

getSubMessage :: (Stream s Identity Char, TextMsg a) => String -> Parsec s () a
getSubMessage :: String -> Parsec s () a
getSubMessage name :: String
name = String -> Parsec s () ()
forall s. Stream s Identity Char => String -> Parsec s () ()
symbol String
name Parsec s () () -> Parsec s () a -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec s () a -> Parsec s () a
forall s a.
Stream s Identity Char =>
Parsec s () a -> Parsec s () a
braces Parsec s () a
forall a s. (TextMsg a, Stream s Identity Char) => Parsec s () a
textGet

-- | This reads message as text-format protobuf from any Parsec-compatible source.
-- Input must be completely consumed.
messageGetText :: (TextMsg a, Stream s Identity Char) => s -> Either String a
messageGetText :: s -> Either String a
messageGetText s :: s
s = case Parsec s () a -> String -> s -> Either ParseError a
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse (Parsec s () a
forall a s. (TextMsg a, Stream s Identity Char) => Parsec s () a
textGet Parsec s () a -> ParsecT s () Identity () -> Parsec s () a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT s () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) "<protobuf>" s
s of
    Left e :: ParseError
e -> String -> Either String a
forall a b. a -> Either a b
Left (ParseError -> String
forall a. Show a => a -> String
show ParseError
e)
    Right m :: a
m -> a -> Either String a
forall a b. b -> Either a b
Right a
m