{- | Here is a simple use of 'parsed' and standard @Streaming@ segmentation devices to 
     parse a file in which groups of numbers are separated by blank lines. Such a problem
     of \'nesting streams\' is described in the @conduit@ context in 
     <http://stackoverflow.com/questions/32957258/how-to-model-nested-streams-with-conduits/32961296 this StackOverflow question> 

> -- $ cat nums.txt
> -- 1
> -- 2
> -- 3
> --
> -- 4
> -- 5
> -- 6
> --
> -- 7
> -- 8

   We will sum the groups and stream the results to standard output:

> import Streaming
> import qualified Streaming.Prelude as S
> import qualified Data.ByteString.Streaming.Char8 as Q
> import qualified Data.Attoparsec.ByteString.Char8 as A
> import qualified Data.Attoparsec.ByteString.Streaming as A
> import Data.Function ((&))
>
> main = Q.getContents           -- raw bytes
>        & A.parsed lineParser   -- stream of parsed `Maybe Int`s; blank lines are `Nothing`
>        & void                  -- drop any unparsed nonsense at the end
>        & S.split Nothing       -- split on blank lines
>        & S.maps S.concat       -- keep `Just x` values in the sub-streams (cp. catMaybes)
>        & S.mapped S.sum        -- sum each substream
>        & S.print               -- stream results to stdout
>
> lineParser = Just <$> A.scientific <* A.endOfLine <|> Nothing <$ A.endOfLine

> -- $ cat nums.txt | ./atto
> -- 6.0
> -- 15.0
> -- 15.0

-} 
module Data.Attoparsec.ByteString.Streaming
    (Message
    , parse
    , parsed
--    , module Data.Attoparsec.ByteString
    )
    where

import qualified Data.ByteString as B
import qualified Data.Attoparsec.ByteString as A
import qualified Data.Attoparsec.Internal.Types as T
import Data.Attoparsec.ByteString
    hiding (IResult(..), Result, eitherResult, maybeResult,
            parse, parseWith, parseTest)

import Streaming hiding (concats, unfold)
import Streaming.Internal (Stream (..)) 
import Data.ByteString.Streaming
import Data.ByteString.Streaming.Internal
import Data.Monoid 

type Message = ([String], String)

{- | The result of a parse (@Either a ([String], String)@), with the unconsumed byte stream.

>>> :set -XOverloadedStrings  -- the string literal below is a streaming bytestring
>>> (r,rest1) <- AS.parse (A.scientific <* A.many' A.space) "12.3  4.56  78.3" 
>>> print r
Left 12.3
>>> (s,rest2) <- AS.parse (A.scientific <* A.many' A.space) rest1
>>> print s
Left 4.56
>>> (t,rest3) <- AS.parse (A.scientific <* A.many' A.space) rest2
>>> print t
Left 78.3
>>> Q.putStrLn rest3

-}
parse :: Monad m 
      => A.Parser a 
      -> ByteString m x -> m (Either a Message, ByteString m x)
parse :: forall (m :: * -> *) a x.
Monad m =>
Parser a -> ByteString m x -> m (Either a Message, ByteString m x)
parse Parser a
parser ByteString m x
bs = do 
  (Either Message a
e,ByteString m x
rest) <- forall (m :: * -> *) a x.
Monad m =>
Parser a -> ByteString m x -> m (Either Message a, ByteString m x)
apply Parser a
parser ByteString m x
bs
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a b. b -> Either a b
Right forall a b. a -> Either a b
Left Either Message a
e, ByteString m x
rest)
{-#INLINE parse #-}

apply :: Monad m
        => A.Parser a
        -> ByteString m x -> m (Either Message a, ByteString m x)
apply :: forall (m :: * -> *) a x.
Monad m =>
Parser a -> ByteString m x -> m (Either Message a, ByteString m x)
apply Parser a
parser = forall {m :: * -> *} {a}.
Monad m =>
ByteStream m a -> m (Either Message a, ByteStream m a)
begin where
  
    begin :: ByteStream m a -> m (Either Message a, ByteStream m a)
begin ByteStream m a
p0 = case ByteStream m a
p0 of
      Go m (ByteStream m a)
m        -> m (ByteStream m a)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m a -> m (Either Message a, ByteStream m a)
begin
      Empty a
r     -> forall {m :: * -> *} {a} {b}.
Monad m =>
(ByteStream m a -> ByteStream m a)
-> IResult ByteString b
-> ByteStream m a
-> m (Either Message b, ByteStream m a)
step forall a. a -> a
id (forall a. Parser a -> ByteString -> Result a
A.parse Parser a
parser forall a. Monoid a => a
mempty) (forall (m :: * -> *) a. Monad m => a -> m a
return a
r)
      Chunk ByteString
bs ByteStream m a
p1 -> if ByteString -> Bool
B.null ByteString
bs -- attoparsec understands "" 
        then ByteStream m a -> m (Either Message a, ByteStream m a)
begin ByteStream m a
p1             -- as eof.
        else forall {m :: * -> *} {a} {b}.
Monad m =>
(ByteStream m a -> ByteStream m a)
-> IResult ByteString b
-> ByteStream m a
-> m (Either Message b, ByteStream m a)
step (forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (forall a. Parser a -> ByteString -> Result a
A.parse Parser a
parser ByteString
bs) ByteStream m a
p1

    step :: (ByteStream m a -> ByteStream m a)
-> IResult ByteString b
-> ByteStream m a
-> m (Either Message b, ByteStream m a)
step ByteStream m a -> ByteStream m a
diff IResult ByteString b
res ByteStream m a
p0 = case IResult ByteString b
res of
      T.Fail ByteString
_ [String]
c String
m -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left ([String]
c,String
m), ByteStream m a -> ByteStream m a
diff ByteStream m a
p0)
      T.Done ByteString
a b
b   -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right b
b, forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ByteStream m a
p0)
      T.Partial ByteString -> IResult ByteString b
k  -> do
        let clean :: ByteStream m a -> m (Either Message b, ByteStream m a)
clean ByteStream m a
p = case ByteStream m a
p of  -- inspect for null chunks before
              Go m (ByteStream m a)
m        -> m (ByteStream m a)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m a -> m (Either Message b, ByteStream m a)
clean  -- feeding attoparsec 
              Empty a
r     -> (ByteStream m a -> ByteStream m a)
-> IResult ByteString b
-> ByteStream m a
-> m (Either Message b, ByteStream m a)
step ByteStream m a -> ByteStream m a
diff (ByteString -> IResult ByteString b
k forall a. Monoid a => a
mempty) (forall (m :: * -> *) a. Monad m => a -> m a
return a
r)
              Chunk ByteString
bs ByteStream m a
p1 | ByteString -> Bool
B.null ByteString
bs -> ByteStream m a -> m (Either Message b, ByteStream m a)
clean ByteStream m a
p1
                          | Bool
otherwise -> (ByteStream m a -> ByteStream m a)
-> IResult ByteString b
-> ByteStream m a
-> m (Either Message b, ByteStream m a)
step (ByteStream m a -> ByteStream m a
diff forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)) (ByteString -> IResult ByteString b
k ByteString
bs) ByteStream m a
p1
        ByteStream m a -> m (Either Message b, ByteStream m a)
clean ByteStream m a
p0
{-#INLINABLE apply #-} 

{-| Apply a parser repeatedly to a stream of bytes, streaming the parsed values, but 
    ending when the parser fails.or the bytes run out.

>>> S.print $ AS.parsed (A.scientific <* A.many' A.space) $ "12.3  4.56  78.9"
12.3
4.56
78.9
18.282
-}
parsed
  :: Monad m
  => A.Parser a     -- ^ Attoparsec parser
  -> ByteString m r -- ^ Raw input
  -> Stream (Of a) m (Either (Message, ByteString m r) r)
parsed :: forall (m :: * -> *) a r.
Monad m =>
Parser a
-> ByteString m r
-> Stream (Of a) m (Either (Message, ByteString m r) r)
parsed Parser a
parser = forall {m :: * -> *} {r}.
Monad m =>
ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin
  where
    begin :: ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin ByteStream m r
p0 = case ByteStream m r
p0 of  -- inspect for null chunks before
            Go m (ByteStream m r)
m        -> forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin -- feeding attoparsec 
            Empty r
r     -> forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (forall a b. b -> Either a b
Right r
r)
            Chunk ByteString
bs ByteStream m r
p1 | ByteString -> Bool
B.null ByteString
bs -> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin ByteStream m r
p1
                        | Bool
otherwise -> (ByteStream m r -> ByteStream m r)
-> Result a
-> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
step (forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>) (forall a. Parser a -> ByteString -> Result a
A.parse Parser a
parser ByteString
bs) ByteStream m r
p1
    step :: (ByteStream m r -> ByteStream m r)
-> Result a
-> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
step ByteStream m r -> ByteStream m r
diffP Result a
res ByteStream m r
p0 = case Result a
res of
      A.Fail ByteString
_ [String]
c String
m -> forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return (forall a b. a -> Either a b
Left (([String]
c,String
m), ByteStream m r -> ByteStream m r
diffP ByteStream m r
p0))
      A.Done ByteString
bs a
a  | ByteString -> Bool
B.null ByteString
bs -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (a
a forall a b. a -> b -> Of a b
:> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin ByteStream m r
p0) 
                   | Bool
otherwise -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (a
a forall a b. a -> b -> Of a b
:> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
begin (forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ByteStream m r
p0))
      A.Partial ByteString -> Result a
k  -> do
        Either r (ByteString, ByteStream m r)
x <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
nextChunk ByteStream m r
p0)
        case Either r (ByteString, ByteStream m r)
x of
          Left r
e -> (ByteStream m r -> ByteStream m r)
-> Result a
-> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
step ByteStream m r -> ByteStream m r
diffP (ByteString -> Result a
k forall a. Monoid a => a
mempty) (forall (m :: * -> *) a. Monad m => a -> m a
return r
e)
          Right (ByteString
bs,ByteStream m r
p1) | ByteString -> Bool
B.null ByteString
bs -> (ByteStream m r -> ByteStream m r)
-> Result a
-> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
step ByteStream m r -> ByteStream m r
diffP Result a
res ByteStream m r
p1
                        | Bool
otherwise  -> (ByteStream m r -> ByteStream m r)
-> Result a
-> ByteStream m r
-> Stream (Of a) m (Either (Message, ByteStream m r) r)
step (ByteStream m r -> ByteStream m r
diffP forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall (m :: * -> *). ByteString -> ByteStream m ()
chunk ByteString
bs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>)) (ByteString -> Result a
k ByteString
bs) ByteStream m r
p1
{-# INLINABLE parsed #-}