pipes-attoparsec-0.0.1: Control/Pipe/Attoparsec.hs
{-# LANGUAGE DeriveDataTypeable #-}
module Control.Pipe.Attoparsec (
ParseError(..),
pipeParser,
) where
import qualified Control.Exception as E
import Control.Pipe
import Control.Pipe.Combinators
import Control.Pipe.Exception
import Data.Attoparsec.Types
import Data.Maybe
import Data.Monoid
import Data.Typeable
-- | A parse error as returned by Attoparsec.
data ParseError
= ParseError {
errorContexts :: [String], -- ^ Contexts where the error occurred.
errorMessage :: String -- ^ Error message.
}
| DivergentParser -- ^ Returned if a parser does not terminate
-- when its input is exhausted.
deriving (Show, Typeable)
instance E.Exception ParseError
-- | Convert a parser continuation into a Pipe.
--
-- To get a parser continuation from a 'Parser', use the @parse@ function of the
-- appropriate Attoparsec module.
pipeParser :: (Monoid a, Monad m) => (a -> IResult a r) -> Pipe a x m (a, Either ParseError r)
pipeParser p = go p
where
go p = do
chunk <- tryAwait
case p (maybe mempty id chunk) of
Fail leftover contexts msg ->
return (leftover, Left $ ParseError contexts msg)
Partial p' ->
if isNothing chunk
then return (mempty, Left DivergentParser)
else go p'
Done leftover result ->
return (leftover, Right result)