@hackage attoparsec-run0.0.2.0

Conveniently run Attoparsec parsers

This package fixes a number of problems with the API that Attoparsec provides for running parsers.

The difficulties stem from the that that Attoparsec's IResult type encompasses three situations: When parsing has succeeded, when parsing has failed, and when parsing is awaiting further input. This is insufficient to describe situations in which we know we are dealing with a subset of these three cases. We address this by introducing two smaller types: FinalResult and ParseError.

FinalResult

FinalResult represents a result that we know not to be partial; for example, the sort of result that we get when running a parser using parseWith.

data FinalResult i a = FinalResult i (Either ParseError a)

ParseError

ParseError represents only the case in which parsing has failed.

data ParseError = ParseError [String] String

Our showParseError function gives an error string in the same format as Attoparsec's eitherResult function.

showParseError :: ParseError -> String

BufferedInput

The BufferedInput type corresponds to two arguments of Attoparsec's parseWith, the initial input and the action to obtain more input.

data BufferedInput m i = BufferedInput i (m i)

In each of the modules Data.Attoparsec.ByteString.Run and Data.Attoparsec.Text.Run, we provide a function called parseStream. This closely corresponds to Attoparsec's parseWith function, but ours returns the more specific FinalResult type, rather than Result, reflecting the fact that a result returned here is never partial.

parseStream :: Monad m =>
    BufferedInput m ByteString -> Parser a -> m (FinalResult ByteString a)

RestorableInput

RestorableInput offers a new way to do streaming parsing that may be more convenient than parseStream and BufferedInput. This type represents an input stream with the ability to push unused input back to it.

data RestorableInput m i = RestorableInput (m i) (i -> m ())

We use this type with the parseAndRestore function:

parseAndRestore :: Monad m =>
    RestorableInput m ByteString -> Parser a -> m (Either ParseError a)

This shifts the burden of storing the unused remainder to feed back into the next parsing step from the user of parseStream to the definer of the RestorableInput.