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
data ParseError
= ParseError {
errorContexts :: [String],
errorMessage :: String
}
| DivergentParser
deriving (Show, Typeable)
instance E.Exception ParseError
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)