grpc-spec
Safe HaskellNone
LanguageHaskell2010

Network.GRPC.Spec.Util.Parser

Description

Incremental parser interface

Intended for qualified import.

import Network.GRPC.Spec.Util.Parser (Parser)
import Network.GRPC.Spec.Util.Parser qualified as Parser
Synopsis

Documentation

data Parser e a Source #

Simple incremental parser

This is used to parse a stream of values, where we know ahead of time for each value how much data to expect (perhaps based on the previous value). Individual values are not parsed incrementally; see consumeExactly or getExactly.

Instances

Instances details
Bifunctor Parser Source # 
Instance details

Defined in Network.GRPC.Spec.Util.Parser

Methods

bimap :: (a -> b) -> (c -> d) -> Parser a c -> Parser b d #

first :: (a -> b) -> Parser a c -> Parser b c #

second :: (b -> c) -> Parser a b -> Parser a c #

Applicative (Parser e) Source # 
Instance details

Defined in Network.GRPC.Spec.Util.Parser

Methods

pure :: a -> Parser e a #

(<*>) :: Parser e (a -> b) -> Parser e a -> Parser e b #

liftA2 :: (a -> b -> c) -> Parser e a -> Parser e b -> Parser e c #

(*>) :: Parser e a -> Parser e b -> Parser e b #

(<*) :: Parser e a -> Parser e b -> Parser e a #

Functor (Parser e) Source # 
Instance details

Defined in Network.GRPC.Spec.Util.Parser

Methods

fmap :: (a -> b) -> Parser e a -> Parser e b #

(<$) :: a -> Parser e b -> Parser e a #

Monad (Parser e) Source # 
Instance details

Defined in Network.GRPC.Spec.Util.Parser

Methods

(>>=) :: Parser e a -> (a -> Parser e b) -> Parser e b #

(>>) :: Parser e a -> Parser e b -> Parser e b #

return :: a -> Parser e a #

MonadFail (Parser String) Source # 
Instance details

Defined in Network.GRPC.Spec.Util.Parser

Methods

fail :: String -> Parser String a #

Construction

consumeExactly Source #

Arguments

:: Int64

Length

-> (ByteString -> Either e a)

Parser

-> Parser e a 

Consume a specified number of bytes

In order to use the Parser interface we must know for each value exactly how big it will be ahead of time. Typically this will be done by first calling consumeExactly for some kind of fixed size header, indicating how big the value actual value is, which will then inform the next call to consumeExactly.

getExactly :: Int64 -> Get a -> Parser String a Source #

Convenience wrapper around consumeExactly

Execution

type IsFinal = Bool Source #

Is this the final chunk in the input?

type Leftover = ByteString Source #

Leftover data

data ProcessResult e b Source #

Result from processing all chunks in the input

See processAll.

Constructors

ProcessError e

Parse error during processing

ProcessedWithFinal b Leftover

Parsing succeeded (compare to ProcessedWithoutFinal)

ProcessedWithoutFinal Leftover

Parsing succeeded, but we did not recognize the final message on time

There are two ways that parsing can terminate: the final few chunks may look like this:

chunk1       -- not marked final
chunk2       -- not marked final
chunk3       -- marked final

or like this:

chunk1       -- not marked final
chunk2       -- not marked final
chunk3       -- not marked final
empty chunk  -- marked final

In the former case, we know that we are processing the final message as we are processing it (ProcessedWithFinal); in the latter case, we realize this only after we receive the final empty chunk.

processAll Source #

Arguments

:: forall m e a b. Monad m 
=> m (ByteString, IsFinal)

Get next chunk

-> (a -> m ())

Process value

-> (a -> m b)

Process final value

-> Parser e a

Parser

-> m (ProcessResult e b) 

Process all incoming data

Returns any unprocessed data. Also returns if we knew that the final result was in fact the final result when we received it (this may or may not be the case, depending on