-- | Taken from Michael Thompson <http://hackage.haskell.org/package/streaming-utils>

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 a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
parsed Parser a
parser = ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin
  where
    begin :: ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin ByteString m r
p0 = case ByteString m r
p0 of  -- inspect for null chunks before
            Go m (ByteString m r)
m        -> m (ByteString m r) -> Stream (Of a) m (ByteString m r)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (ByteString m r)
m Stream (Of a) m (ByteString m r)
-> (ByteString m r
    -> Stream (Of a) m (Either (Message, ByteString m r) r))
-> Stream (Of a) m (Either (Message, ByteString m r) r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin -- feeding attoparsec 
            Empty r
r     -> Either (Message, ByteString m r) r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (r -> Either (Message, ByteString m r) r
forall a b. b -> Either a b
Right r
r)
            Chunk ByteString
bs ByteString m r
p1 | ByteString -> Bool
B.null ByteString
bs -> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin ByteString m r
p1
                        | Bool
otherwise -> (ByteString m r -> ByteString m r)
-> Result a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
step (ByteString -> ByteStream m ()
forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs ByteStream m () -> ByteString m r -> ByteString m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (Parser a -> ByteString -> Result a
forall a. Parser a -> ByteString -> Result a
A.parse Parser a
parser ByteString
bs) ByteString m r
p1
    step :: (ByteString m r -> ByteString m r)
-> Result a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
step ByteString m r -> ByteString m r
diffP Result a
res ByteString m r
p0 = case Result a
res of
      A.Fail ByteString
_ [String]
c String
m -> Either (Message, ByteString m r) r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return ((Message, ByteString m r) -> Either (Message, ByteString m r) r
forall a b. a -> Either a b
Left (([String]
c,String
m), ByteString m r -> ByteString m r
diffP ByteString m r
p0))
      A.Done ByteString
bs a
a  | ByteString -> Bool
B.null ByteString
bs -> Of a (Stream (Of a) m (Either (Message, ByteString m r) r))
-> Stream (Of a) m (Either (Message, ByteString m r) r)
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (a
a a
-> Stream (Of a) m (Either (Message, ByteString m r) r)
-> Of a (Stream (Of a) m (Either (Message, ByteString m r) r))
forall a b. a -> b -> Of a b
:> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin ByteString m r
p0) 
                   | Bool
otherwise -> Of a (Stream (Of a) m (Either (Message, ByteString m r) r))
-> Stream (Of a) m (Either (Message, ByteString m r) r)
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (a
a a
-> Stream (Of a) m (Either (Message, ByteString m r) r)
-> Of a (Stream (Of a) m (Either (Message, ByteString m r) r))
forall a b. a -> b -> Of a b
:> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
begin (ByteString -> ByteStream m ()
forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs ByteStream m () -> ByteString m r -> ByteString m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ByteString m r
p0))
      A.Partial ByteString -> Result a
k  -> do
        Either r (ByteString, ByteString m r)
x <- m (Either r (ByteString, ByteString m r))
-> Stream (Of a) m (Either r (ByteString, ByteString m r))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ByteString m r -> m (Either r (ByteString, ByteString m r))
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
nextChunk ByteString m r
p0)
        case Either r (ByteString, ByteString m r)
x of
          Left r
e -> (ByteString m r -> ByteString m r)
-> Result a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
step ByteString m r -> ByteString m r
diffP (ByteString -> Result a
k ByteString
forall a. Monoid a => a
mempty) (r -> ByteString m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
e)
          Right (ByteString
bs,ByteString m r
p1) | ByteString -> Bool
B.null ByteString
bs -> (ByteString m r -> ByteString m r)
-> Result a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
step ByteString m r -> ByteString m r
diffP Result a
res ByteString m r
p1
                        | Bool
otherwise  -> (ByteString m r -> ByteString m r)
-> Result a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
step (ByteString m r -> ByteString m r
diffP (ByteString m r -> ByteString m r)
-> (ByteString m r -> ByteString m r)
-> ByteString m r
-> ByteString m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> ByteStream m ()
forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs ByteStream m () -> ByteString m r -> ByteString m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)) (ByteString -> Result a
k ByteString
bs) ByteString m r
p1
{-# INLINABLE parsed #-}