module Data.Attoparsec.Iteratee
( parserToIteratee ) where
import qualified Data.Attoparsec as Atto
import Data.Attoparsec hiding (many, Result(..))
import Data.ByteString (ByteString)
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.Iteratee
import Data.Iteratee.WrappedByteString
import Data.Word
type Stream = StreamG WrappedByteString Word8
type IterV m = IterGV WrappedByteString Word8 m
parserToIteratee :: (Monad m) =>
Parser a
-> IterateeG WrappedByteString Word8 m a
parserToIteratee p = IterateeG $ f (\s -> parse p s)
where
f :: (Monad m) =>
(ByteString -> Atto.Result a)
-> Stream
-> m (IterV m a)
f k (EOF Nothing) = finalChunk $ k S.empty
f _ (EOF (Just e)) = reportError e
f k (Chunk s) = let s' = S.concat $ L.toChunks $ fromWrap s
in if S.null s'
then return $ Cont (IterateeG $ f k) Nothing
else chunk s' k
finalChunk :: (Monad m) => Atto.Result a -> m (IterV m a)
finalChunk (Atto.Fail _ _ m) =
return $ Cont (error $ show m)
(Just $ Err m)
finalChunk (Atto.Done rest r) =
return $ Done r (Chunk $ toWrap $ L.fromChunks [rest])
finalChunk (Atto.Partial _) =
return $ Cont (error "parser did not produce a value")
(Just $ Err "parser did not produce a value")
reportError e = return $ Cont (error $ show e) (Just e)
chunk :: (Monad m) =>
ByteString
-> (ByteString -> Atto.Result a)
-> m (IterV m a)
chunk s k = do
let r = k s
case r of
(Atto.Fail _ _ m) -> return $
Cont (throwErr (Err m)) (Just $ Err m)
(Atto.Done rest x) -> return $ Done x (Chunk $ toWrap $ L.fromChunks [rest])
(Atto.Partial z) -> return $
Cont (IterateeG $ f z) Nothing
toWrap :: L.ByteString -> WrappedByteString Word8
toWrap = WrapBS . S.concat . L.toChunks
fromWrap :: WrappedByteString Word8 -> L.ByteString
fromWrap = L.fromChunks . (:[]) . unWrap