-- | Taken from Michael Thompson module Data.Attoparsec.ByteString.Streaming where import qualified Data.Attoparsec.ByteString as A import Data.ByteString.Streaming import Data.ByteString.Streaming.Internal import qualified Data.ByteString as B import Streaming.Internal (Stream (..)) import Streaming hiding (concats, unfold) type Message = ([String], String) -- | The parsed function from @streaming-utils@ parsed :: Monad m => A.Parser a -- ^ Attoparsec parser -> ByteString m r -- ^ Raw input -> Stream (Of a) m (Either (Message, ByteString m r) r) parsed parser = begin where begin p0 = case p0 of -- inspect for null chunks before Go m -> lift m >>= begin -- feeding attoparsec Empty r -> Return (Right r) Chunk bs p1 | B.null bs -> begin p1 | otherwise -> step (chunk bs >>) (A.parse parser bs) p1 step diffP res p0 = case res of A.Fail _ c m -> Return (Left ((c,m), diffP p0)) A.Done bs a | B.null bs -> Step (a :> begin p0) | otherwise -> Step (a :> begin (chunk bs >> p0)) A.Partial k -> do x <- lift (nextChunk p0) case x of Left e -> step diffP (k mempty) (return e) Right (bs,p1) | B.null bs -> step diffP res p1 | otherwise -> step (diffP . (chunk bs >>)) (k bs) p1 {-# INLINABLE parsed #-}