wobsurv-0.1.0: library/Wobsurv/Util/PipesAttoparsec.hs
-- |
-- Utils for integration of Pipes and Attoparsec.
module Wobsurv.Util.PipesAttoparsec where
import BasePrelude
import Pipes.Parse hiding (execStateT, evalStateT)
import Control.Monad.Trans.State
import qualified Data.Attoparsec.ByteString.Char8 as Attoparsec
import qualified Data.ByteString as BS
type BS =
BS.ByteString
type AttoParser =
Attoparsec.Parser
type PipesParser m r =
Parser BS m r
data Error =
UnfinishedInput |
ConsumedTooMuch |
AttoparsecError ![String] !String
deriving (Show)
liftParserWithLimit :: (Monad m) => Int -> AttoParser a -> PipesParser m (Either Error a)
liftParserWithLimit limit parser =
evalStateT (loop initCont) limit
where
loop cont =
do
chunk <- return . fromMaybe BS.empty =<< lift draw
modify (subtract (BS.length chunk))
n <- get
if n < 0
then
return $ Left $ ConsumedTooMuch
else
case cont chunk of
Attoparsec.Fail remainder context message ->
do
lift $ unDraw remainder
return $ Left $ AttoparsecError context message
Attoparsec.Partial cont' ->
if BS.length chunk > 0
then loop cont'
else return $ Left $ UnfinishedInput
Attoparsec.Done remainder result ->
do
lift $ unDraw remainder
return $ Right result
initCont =
Attoparsec.parse parser