#include "inline.hs"

-- |
-- Module      : Streamly.Internal.Data.Parser.ParserD
-- Copyright   : (c) 2020 Composewell Technologies
-- License     : BSD-3-Clause
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC
--
-- Direct style parser implementation with stream fusion.

module Streamly.Internal.Data.Parser.ParserD
    (
      Parser (..)
    , ParseError (..)
    , Step (..)
    , Initial (..)
    , rmapM

    -- * Downgrade to Fold
    , toFold

    -- First order parsers
    -- * Accumulators
    , fromFold
    , fromPure
    , fromEffect
    , die
    , dieM

    -- * Element parsers
    , peek
    , eof
    , satisfy
    , next
    , maybe
    , either

    -- * Sequence parsers
    --
    -- Parsers chained in series, if one parser terminates the composition
    -- terminates. Currently we are using folds to collect the output of the
    -- parsers but we can use Parsers instead of folds to make the composition
    -- more powerful. For example, we can do:
    --
    -- sliceSepByMax cond n p = sliceBy cond (take n p)
    -- sliceSepByBetween cond m n p = sliceBy cond (takeBetween m n p)
    -- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p)
    --
    -- Grab a sequence of input elements without inspecting them
    , takeBetween
    -- , take -- take   -- takeBetween 0 n
    -- , takeLE1 -- take1 -- takeBetween 1 n
    , takeEQ -- takeBetween n n
    , takeGE -- takeBetween n maxBound

    -- Grab a sequence of input elements by inspecting them
    , takeP
    , lookAhead
    , takeWhile
    , takeWhile1
    , sliceSepByP
    -- , sliceSepByBetween
    , sliceBeginWith
    -- , sliceSepWith
    --
    -- , frameSepBy -- parse frames escaped by an escape char/sequence
    -- , frameEndWith
    --
    , wordBy
    , groupBy
    , groupByRolling
    , groupByRollingEither
    , eqBy
    -- , prefixOf -- match any prefix of a given string
    -- , suffixOf -- match any suffix of a given string
    -- , infixOf -- match any substring of a given string

    -- ** Spanning
    , span
    , spanBy
    , spanByRolling

    -- Second order parsers (parsers using parsers)
    -- * Binary Combinators

    -- ** Sequential Applicative
    , serialWith
    , split_

    -- ** Parallel Applicatives
    , teeWith
    , teeWithFst
    , teeWithMin
    -- , teeTill -- like manyTill but parallel

    -- ** Sequential Interleaving
    -- Use two folds, run a primary parser, its rejected values go to the
    -- secondary parser.
    , deintercalate

    -- ** Sequential Alternative
    , alt

    -- ** Parallel Alternatives
    , shortest
    , longest
    -- , fastest

    -- * N-ary Combinators
    -- ** Sequential Collection
    , sequence
    , concatMap

    -- ** Sequential Repetition
    , count
    , countBetween
    -- , countBetweenTill

    , many
    , some
    , manyTill

    -- -- ** Special cases
    -- XXX traditional implmentations of these may be of limited use. For
    -- example, consider parsing lines separated by "\r\n". The main parser
    -- will have to detect and exclude the sequence "\r\n" anyway so that we
    -- can apply the "sep" parser.
    --
    -- We can instead implement these as special cases of deintercalate.
    --
    -- , endBy
    -- , sepBy
    -- , sepEndBy
    -- , beginBy
    -- , sepBeginBy
    -- , sepAroundBy

    -- -- * Distribution
    --
    -- A simple and stupid impl would be to just convert the stream to an array
    -- and give the array reference to all consumers. The array can be grown on
    -- demand by any consumer and truncated when nonbody needs it.
    --
    -- -- ** Distribute to collection
    -- -- ** Distribute to repetition

    -- -- ** Interleaved collection
    -- Round robin
    -- Priority based
    -- -- ** Interleaved repetition
    -- repeat one parser and when it fails run an error recovery parser
    -- e.g. to find a key frame in the stream after an error

    -- ** Collection of Alternatives
    -- , shortestN
    -- , longestN
    -- , fastestN -- first N successful in time
    -- , choiceN  -- first N successful in position
    , choice   -- first successful in position

    -- -- ** Repeated Alternatives
    -- , retryMax    -- try N times
    -- , retryUntil  -- try until successful
    -- , retryUntilN -- try until successful n times
    )
where

import Control.Exception (assert, Exception)
import Control.Monad (when)
import Control.Monad.Catch (MonadCatch, MonadThrow(..))
import Fusion.Plugin.Types (Fuse(..))
import Streamly.Internal.Data.Fold.Type (Fold(..))
import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))

import qualified Streamly.Internal.Data.Fold.Type as FL

import Prelude hiding
       (any, all, take, takeWhile, sequence, concatMap, maybe, either, span)
import Streamly.Internal.Data.Parser.ParserD.Tee
import Streamly.Internal.Data.Parser.ParserD.Type

--
-- $setup
-- >>> :m
-- >>> import Prelude hiding ()
-- >>> import qualified Streamly.Prelude as Stream
-- >>> import qualified Streamly.Internal.Data.Stream.IsStream as Stream
-- >>> import qualified Streamly.Data.Fold as Fold
-- >>> import qualified Streamly.Internal.Data.Parser as Parser

-------------------------------------------------------------------------------
-- Downgrade a parser to a Fold
-------------------------------------------------------------------------------

data ParserToFoldError =
      InitialError String
    | PartialError Int
    | ContinueError Int
    | DoneError Int
    | ErrorError String
    deriving Int -> ParserToFoldError -> ShowS
[ParserToFoldError] -> ShowS
ParserToFoldError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParserToFoldError] -> ShowS
$cshowList :: [ParserToFoldError] -> ShowS
show :: ParserToFoldError -> String
$cshow :: ParserToFoldError -> String
showsPrec :: Int -> ParserToFoldError -> ShowS
$cshowsPrec :: Int -> ParserToFoldError -> ShowS
Show

instance Exception ParserToFoldError

-- | See 'Streamly.Internal.Data.Parser.toFold'.
--
-- /Internal/
--
{-# INLINE toFold #-}
toFold :: MonadThrow m => Parser m a b -> Fold m a b
toFold :: forall (m :: * -> *) a b.
MonadThrow m =>
Parser m a b -> Fold m a b
toFold (Parser s -> a -> m (Step s b)
pstep m (Initial s b)
pinitial s -> m b
pextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold s -> a -> m (Step s b)
step m (Step s b)
initial s -> m b
pextract

    where

    initial :: m (Step s b)
initial = do
        Initial s b
r <- m (Initial s b)
pinitial
        case Initial s b
r of
            IPartial s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial s
s
            IDone b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
FL.Done b
b
            IError String
err -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParserToFoldError
InitialError String
err

    step :: s -> a -> m (Step s b)
step s
st a
a = do
        Step s b
r <- s -> a -> m (Step s b)
pstep s
st a
a
        case Step s b
r of
            Partial Int
0 s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial s
s
            Continue Int
0 s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Step s b
FL.Partial s
s
            Done Int
0 b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Step s b
FL.Done b
b
            Partial Int
n s
_ -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ Int -> ParserToFoldError
PartialError Int
n
            Continue Int
n s
_ -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ Int -> ParserToFoldError
ContinueError Int
n
            Done Int
n b
_ -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ Int -> ParserToFoldError
DoneError Int
n
            Error String
err -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParserToFoldError
ErrorError String
err

-------------------------------------------------------------------------------
-- Upgrade folds to parses
-------------------------------------------------------------------------------
--
-- | See 'Streamly.Internal.Data.Parser.fromFold'.
--
-- /Pre-release/
--
{-# INLINE fromFold #-}
fromFold :: Monad m => Fold m a b -> Parser m a b
fromFold :: forall (m :: * -> *) a b. Monad m => Fold m a b -> Parser m a b
fromFold (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser s -> a -> m (Step s b)
step m (Initial s b)
initial s -> m b
fextract

    where

    initial :: m (Initial s b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s1 -> forall s b. s -> Initial s b
IPartial s
s1
                  FL.Done b
b -> forall s b. b -> Initial s b
IDone b
b

    step :: s -> a -> m (Step s b)
step s
s a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 s
s1
                  FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b

-------------------------------------------------------------------------------
-- Failing Parsers
-------------------------------------------------------------------------------

-- | See 'Streamly.Internal.Data.Parser.peek'.
--
-- /Pre-release/
--
{-# INLINE peek #-}
peek :: MonadThrow m => Parser m a a
peek :: forall (m :: * -> *) a. MonadThrow m => Parser m a a
peek = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *} {b} {s}. Monad m => () -> b -> m (Step s b)
step forall {b}. m (Initial () b)
initial forall {m :: * -> *} {a}. MonadThrow m => () -> m a
extract

    where

    initial :: m (Initial () b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()

    step :: () -> b -> m (Step s b)
step () b
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
1 b
a

    extract :: () -> m a
extract () = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
"peek: end of input"

-- | See 'Streamly.Internal.Data.Parser.eof'.
--
-- /Pre-release/
--
{-# INLINE eof #-}
eof :: Monad m => Parser m a ()
eof :: forall (m :: * -> *) a. Monad m => Parser m a ()
eof = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *} {p} {s} {b}.
Monad m =>
() -> p -> m (Step s b)
step forall {b}. m (Initial () b)
initial forall (m :: * -> *) a. Monad m => a -> m a
return

    where

    initial :: m (Initial () b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()

    step :: () -> p -> m (Step s b)
step () p
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
Error String
"eof: not at end of input"

-- | See 'Streamly.Internal.Data.Parser.satisfy'.
--
-- /Pre-release/
--
{-# INLINE satisfy #-}
satisfy :: MonadThrow m => (a -> Bool) -> Parser m a a
satisfy :: forall (m :: * -> *) a. MonadThrow m => (a -> Bool) -> Parser m a a
satisfy a -> Bool
predicate = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *} {s}. Monad m => () -> a -> m (Step s a)
step forall {b}. m (Initial () b)
initial forall {m :: * -> *} {p} {a}. MonadThrow m => p -> m a
extract

    where

    initial :: m (Initial () b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()

    step :: () -> a -> m (Step s a)
step () a
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        if a -> Bool
predicate a
a
        then forall s b. Int -> b -> Step s b
Done Int
0 a
a
        else forall s b. String -> Step s b
Error String
"satisfy: predicate failed"

    extract :: p -> m a
extract p
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
"satisfy: end of input"

-- | See 'Streamly.Internal.Data.Parser.next'.
--
-- /Pre-release/
--
{-# INLINE next #-}
next :: Monad m => Parser m a (Maybe a)
next :: forall (m :: * -> *) a. Monad m => Parser m a (Maybe a)
next = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {f :: * -> *} {p} {a} {s}.
Applicative f =>
p -> a -> f (Step s (Maybe a))
step forall {b}. m (Initial () b)
initial forall {f :: * -> *} {p} {a}. Applicative f => p -> f (Maybe a)
extract
  where
  initial :: m (Initial () b)
initial = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()
  step :: p -> a -> f (Step s (Maybe a))
step p
_ a
a = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
0 (forall a. a -> Maybe a
Just a
a)
  extract :: p -> f (Maybe a)
extract p
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing

-- | See 'Streamly.Internal.Data.Parser.maybe'.
--
-- /Pre-release/
--
{-# INLINE maybe #-}
maybe :: MonadThrow m => (a -> Maybe b) -> Parser m a b
maybe :: forall (m :: * -> *) a b.
MonadThrow m =>
(a -> Maybe b) -> Parser m a b
maybe a -> Maybe b
parserF = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *} {s}. Monad m => () -> a -> m (Step s b)
step forall {b}. m (Initial () b)
initial forall {m :: * -> *} {p} {a}. MonadThrow m => p -> m a
extract

    where

    initial :: m (Initial () b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()

    step :: () -> a -> m (Step s b)
step () a
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        case a -> Maybe b
parserF a
a of
            Just b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b
            Maybe b
Nothing -> forall s b. String -> Step s b
Error String
"maybe: predicate failed"

    extract :: p -> m a
extract p
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
"maybe: end of input"

-- | See 'Streamly.Internal.Data.Parser.either'.
--
-- /Pre-release/
--
{-# INLINE either #-}
either :: MonadThrow m => (a -> Either String b) -> Parser m a b
either :: forall (m :: * -> *) a b.
MonadThrow m =>
(a -> Either String b) -> Parser m a b
either a -> Either String b
parserF = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *} {s}. Monad m => () -> a -> m (Step s b)
step forall {b}. m (Initial () b)
initial forall {m :: * -> *} {p} {a}. MonadThrow m => p -> m a
extract

    where

    initial :: m (Initial () b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial ()

    step :: () -> a -> m (Step s b)
step () a
a = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        case a -> Either String b
parserF a
a of
            Right b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b
            Left String
err -> forall s b. String -> Step s b
Error forall a b. (a -> b) -> a -> b
$ String
"either: " forall a. [a] -> [a] -> [a]
++ String
err

    extract :: p -> m a
extract p
_ = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
"either: end of input"

-------------------------------------------------------------------------------
-- Taking elements
-------------------------------------------------------------------------------

-- Required to fuse "take" with "many" in "chunksOf", for ghc-9.x
{-# ANN type Tuple'Fused Fuse #-}
data Tuple'Fused a b = Tuple'Fused !a !b deriving Int -> Tuple'Fused a b -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Tuple'Fused a b -> ShowS
forall a b. (Show a, Show b) => [Tuple'Fused a b] -> ShowS
forall a b. (Show a, Show b) => Tuple'Fused a b -> String
showList :: [Tuple'Fused a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [Tuple'Fused a b] -> ShowS
show :: Tuple'Fused a b -> String
$cshow :: forall a b. (Show a, Show b) => Tuple'Fused a b -> String
showsPrec :: Int -> Tuple'Fused a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Tuple'Fused a b -> ShowS
Show

-- | See 'Streamly.Internal.Data.Parser.takeBetween'.
--
-- /Pre-release/
--
{-# INLINE takeBetween #-}
takeBetween :: MonadCatch m => Int -> Int -> Fold m a b -> Parser m a b
takeBetween :: forall (m :: * -> *) a b.
MonadCatch m =>
Int -> Int -> Fold m a b -> Parser m a b
takeBetween Int
low Int
high (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) =

    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser Tuple'Fused Int s -> a -> m (Step (Tuple'Fused Int s) b)
step m (Initial (Tuple'Fused Int s) b)
initial ((Int -> String) -> Tuple'Fused Int s -> m b
extract forall {a}. Show a => a -> String
streamErr)

    where

    streamErr :: a -> String
streamErr a
i =
           String
"takeBetween: Expecting alteast " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
low
        forall a. [a] -> [a] -> [a]
++ String
" elements, got " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show a
i

    invalidRange :: String
invalidRange =
        String
"takeBetween: lower bound - " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
low
            forall a. [a] -> [a] -> [a]
++ String
" is greater than higher bound - " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
high

    foldErr :: Int -> String
    foldErr :: Int -> String
foldErr Int
i =
        String
"takeBetween: the collecting fold terminated after"
            forall a. [a] -> [a] -> [a]
++ String
" consuming" forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
i forall a. [a] -> [a] -> [a]
++ String
" elements"
            forall a. [a] -> [a] -> [a]
++ String
" minimum" forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
low forall a. [a] -> [a] -> [a]
++ String
" elements needed"

    -- Exactly the same as snext except different constructors, we can possibly
    -- deduplicate the two.
    {-# INLINE inext #-}
    inext :: Int -> Step s b -> m (Initial (Tuple'Fused Int s) b)
inext Int
i Step s b
res =
        let i1 :: Int
i1 = Int
i forall a. Num a => a -> a -> a
+ Int
1
        in case Step s b
res of
            FL.Partial s
s -> do
                let s1 :: Tuple'Fused Int s
s1 = forall a b. a -> b -> Tuple'Fused a b
Tuple'Fused Int
i1 s
s
                if Int
i1 forall a. Ord a => a -> a -> Bool
< Int
high
                -- XXX ideally this should be a Continue instead
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial Tuple'Fused Int s
s1
                else forall s b. b -> Initial s b
IDone forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> String) -> Tuple'Fused Int s -> m b
extract Int -> String
foldErr Tuple'Fused Int s
s1
            FL.Done b
b ->
                forall (m :: * -> *) a. Monad m => a -> m a
return
                    forall a b. (a -> b) -> a -> b
$ if Int
i1 forall a. Ord a => a -> a -> Bool
>= Int
low
                      then forall s b. b -> Initial s b
IDone b
b
                      else forall s b. String -> Initial s b
IError (Int -> String
foldErr Int
i1)

    initial :: m (Initial (Tuple'Fused Int s) b)
initial = do
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
low forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
high forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
low forall a. Ord a => a -> a -> Bool
> Int
high)
            forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
invalidRange

        m (Step s b)
finitial forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Step s b -> m (Initial (Tuple'Fused Int s) b)
inext (-Int
1)

    -- Keep the impl same as inext
    {-# INLINE snext #-}
    snext :: Int -> Step s b -> m (Step (Tuple'Fused Int s) b)
snext Int
i Step s b
res =
        let i1 :: Int
i1 = Int
i forall a. Num a => a -> a -> a
+ Int
1
        in case Step s b
res of
            FL.Partial s
s -> do
                let s1 :: Tuple'Fused Int s
s1 = forall a b. a -> b -> Tuple'Fused a b
Tuple'Fused Int
i1 s
s
                if Int
i1 forall a. Ord a => a -> a -> Bool
< Int
high
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
0 Tuple'Fused Int s
s1
                else forall s b. Int -> b -> Step s b
Done Int
0 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> String) -> Tuple'Fused Int s -> m b
extract Int -> String
foldErr Tuple'Fused Int s
s1
            FL.Done b
b ->
                forall (m :: * -> *) a. Monad m => a -> m a
return
                    forall a b. (a -> b) -> a -> b
$ if Int
i1 forall a. Ord a => a -> a -> Bool
>= Int
low
                      then forall s b. Int -> b -> Step s b
Done Int
0 b
b
                      else forall s b. String -> Step s b
Error (Int -> String
foldErr Int
i1)

    step :: Tuple'Fused Int s -> a -> m (Step (Tuple'Fused Int s) b)
step (Tuple'Fused Int
i s
s) a
a = s -> a -> m (Step s b)
fstep s
s a
a forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Step s b -> m (Step (Tuple'Fused Int s) b)
snext Int
i

    extract :: (Int -> String) -> Tuple'Fused Int s -> m b
extract Int -> String
f (Tuple'Fused Int
i s
s)
        | Int
i forall a. Ord a => a -> a -> Bool
>= Int
low Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
<= Int
high = s -> m b
fextract s
s
        | Bool
otherwise = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError (Int -> String
f Int
i)

-- | See 'Streamly.Internal.Data.Parser.takeEQ'.
--
-- /Pre-release/
--
{-# INLINE takeEQ #-}
takeEQ :: MonadThrow m => Int -> Fold m a b -> Parser m a b
takeEQ :: forall (m :: * -> *) a b.
MonadThrow m =>
Int -> Fold m a b -> Parser m a b
takeEQ Int
n (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step m (Initial (Tuple' Int s) b)
initial forall {a}. (Eq a, Num a, Show a) => Tuple' a s -> m b
extract

    where

    cnt :: Int
cnt = forall a. Ord a => a -> a -> a
max Int
n Int
0

    initial :: m (Initial (Tuple' Int s) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Step s b
res of
            FL.Partial s
s -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
0 s
s
            FL.Done b
b ->
                if Int
cnt forall a. Eq a => a -> a -> Bool
== Int
0
                then forall s b. b -> Initial s b
IDone b
b
                else forall s b. String -> Initial s b
IError
                         forall a b. (a -> b) -> a -> b
$ String
"takeEQ: Expecting exactly " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                             forall a. [a] -> [a] -> [a]
++ String
" elements, fold terminated without"
                             forall a. [a] -> [a] -> [a]
++ String
" consuming any elements"

    step :: Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step (Tuple' Int
i s
r) a
a
        | Int
i1 forall a. Ord a => a -> a -> Bool
< Int
cnt = do
            Step s b
res <- s -> a -> m (Step s b)
fstep s
r a
a
            forall (m :: * -> *) a. Monad m => a -> m a
return
                forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                    FL.Partial s
s -> forall s b. Int -> s -> Step s b
Continue Int
0 forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
i1 s
s
                    FL.Done b
_ ->
                        forall s b. String -> Step s b
Error
                            forall a b. (a -> b) -> a -> b
$ String
"takeEQ: Expecting exactly " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                                forall a. [a] -> [a] -> [a]
++ String
" elements, fold terminated on " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
i1
        | Int
i1 forall a. Eq a => a -> a -> Bool
== Int
cnt = do
            Step s b
res <- s -> a -> m (Step s b)
fstep s
r a
a
            forall s b. Int -> b -> Step s b
Done Int
0
                forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Step s b
res of
                        FL.Partial s
s -> s -> m b
fextract s
s
                        FL.Done b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return b
b
        -- XXX we should not reach here when initial returns Step type
        -- reachable only when n == 0
        | Bool
otherwise = forall s b. Int -> b -> Step s b
Done Int
1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
r

        where

        i1 :: Int
i1 = Int
i forall a. Num a => a -> a -> a
+ Int
1

    extract :: Tuple' a s -> m b
extract (Tuple' a
i s
r)
        | a
i forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& Int
cnt forall a. Eq a => a -> a -> Bool
== Int
0 = s -> m b
fextract s
r
        | Bool
otherwise =
            forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
                forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError
                forall a b. (a -> b) -> a -> b
$ String
"takeEQ: Expecting exactly " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                    forall a. [a] -> [a] -> [a]
++ String
" elements, input terminated on " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show a
i

-- | See 'Streamly.Internal.Data.Parser.takeGE'.
--
-- /Pre-release/
--
{-# INLINE takeGE #-}
takeGE :: MonadThrow m => Int -> Fold m a b -> Parser m a b
takeGE :: forall (m :: * -> *) a b.
MonadThrow m =>
Int -> Fold m a b -> Parser m a b
takeGE Int
n (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step m (Initial (Tuple' Int s) b)
initial Tuple' Int s -> m b
extract

    where

    cnt :: Int
cnt = forall a. Ord a => a -> a -> a
max Int
n Int
0
    initial :: m (Initial (Tuple' Int s) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Step s b
res of
            FL.Partial s
s -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
0 s
s
            FL.Done b
b ->
                if Int
cnt forall a. Eq a => a -> a -> Bool
== Int
0
                then forall s b. b -> Initial s b
IDone b
b
                else forall s b. String -> Initial s b
IError
                         forall a b. (a -> b) -> a -> b
$ String
"takeGE: Expecting at least " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                             forall a. [a] -> [a] -> [a]
++ String
" elements, fold terminated without"
                             forall a. [a] -> [a] -> [a]
++ String
" consuming any elements"

    step :: Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step (Tuple' Int
i s
r) a
a
        | Int
i1 forall a. Ord a => a -> a -> Bool
< Int
cnt = do
            Step s b
res <- s -> a -> m (Step s b)
fstep s
r a
a
            forall (m :: * -> *) a. Monad m => a -> m a
return
                forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                      FL.Partial s
s -> forall s b. Int -> s -> Step s b
Continue Int
0 forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
i1 s
s
                      FL.Done b
_ ->
                        forall s b. String -> Step s b
Error
                            forall a b. (a -> b) -> a -> b
$ String
"takeGE: Expecting at least " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                                forall a. [a] -> [a] -> [a]
++ String
" elements, fold terminated on " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
i1
        | Bool
otherwise = do
            Step s b
res <- s -> a -> m (Step s b)
fstep s
r a
a
            forall (m :: * -> *) a. Monad m => a -> m a
return
                forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                      FL.Partial s
s -> forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
i1 s
s
                      FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b

        where

        i1 :: Int
i1 = Int
i forall a. Num a => a -> a -> a
+ Int
1

    extract :: Tuple' Int s -> m b
extract (Tuple' Int
i s
r)
        | Int
i forall a. Ord a => a -> a -> Bool
>= Int
cnt = s -> m b
fextract s
r
        | Bool
otherwise =
            forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
                forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError
                forall a b. (a -> b) -> a -> b
$ String
"takeGE: Expecting at least " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
cnt
                    forall a. [a] -> [a] -> [a]
++ String
" elements, input terminated on " forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show Int
i

-- | See 'Streamly.Internal.Data.Parser.takeWhile'.
--
-- /Pre-release/
--
{-# INLINE takeWhile #-}
takeWhile :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
takeWhile :: forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
takeWhile a -> Bool
predicate (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) =
    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser s -> a -> m (Step s b)
step m (Initial s b)
initial s -> m b
fextract

    where

    initial :: m (Initial s b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Step s b
res of
            FL.Partial s
s -> forall s b. s -> Initial s b
IPartial s
s
            FL.Done b
b -> forall s b. b -> Initial s b
IDone b
b

    step :: s -> a -> m (Step s b)
step s
s a
a =
        if a -> Bool
predicate a
a
        then do
            Step s b
fres <- s -> a -> m (Step s b)
fstep s
s a
a
            forall (m :: * -> *) a. Monad m => a -> m a
return
                forall a b. (a -> b) -> a -> b
$ case Step s b
fres of
                      FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 s
s1
                      FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b
        else forall s b. Int -> b -> Step s b
Done Int
1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
s

-- | See 'Streamly.Internal.Data.Parser.takeWhile1'.
--
-- /Pre-release/
--
{-# INLINE takeWhile1 #-}
takeWhile1 :: MonadThrow m => (a -> Bool) -> Fold m a b -> Parser m a b
takeWhile1 :: forall (m :: * -> *) a b.
MonadThrow m =>
(a -> Bool) -> Fold m a b -> Parser m a b
takeWhile1 a -> Bool
predicate (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) =
    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {a}. Either s s -> a -> m (Step (Either a s) b)
step forall {b} {b}. m (Initial (Either s b) b)
initial forall {a}. Either a s -> m b
extract

    where

    initial :: m (Initial (Either s b) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Step s b
res of
            FL.Partial s
s -> forall s b. s -> Initial s b
IPartial (forall a b. a -> Either a b
Left s
s)
            FL.Done b
_ ->
                forall s b. String -> Initial s b
IError
                    forall a b. (a -> b) -> a -> b
$ String
"takeWhile1: fold terminated without consuming:"
                          forall a. [a] -> [a] -> [a]
++ String
" any element"

    {-# INLINE process #-}
    process :: s -> a -> m (Step (Either a s) b)
process s
s a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall a b. b -> Either a b
Right s
s1)
                  FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b

    step :: Either s s -> a -> m (Step (Either a s) b)
step (Left s
s) a
a =
        if a -> Bool
predicate a
a
        then forall {a}. s -> a -> m (Step (Either a s) b)
process s
s a
a
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
Error String
"takeWhile1: predicate failed on first element"
    step (Right s
s) a
a =
        if a -> Bool
predicate a
a
        then forall {a}. s -> a -> m (Step (Either a s) b)
process s
s a
a
        else do
            b
b <- s -> m b
fextract s
s
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
1 b
b

    extract :: Either a s -> m b
extract (Left a
_) = forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError String
"takeWhile1: end of input"
    extract (Right s
s) = s -> m b
fextract s
s

-- | See 'Streamly.Internal.Data.Parser.sliceSepByP'.
--
-- /Pre-release/
--
sliceSepByP :: MonadCatch m =>
    (a -> Bool) -> Parser m a b -> Parser m a b
sliceSepByP :: forall (m :: * -> *) a b.
MonadCatch m =>
(a -> Bool) -> Parser m a b -> Parser m a b
sliceSepByP a -> Bool
cond (Parser s -> a -> m (Step s b)
pstep m (Initial s b)
pinitial s -> m b
pextract) =

    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser s -> a -> m (Step s b)
step m (Initial s b)
initial s -> m b
pextract

    where

    initial :: m (Initial s b)
initial = m (Initial s b)
pinitial

    step :: s -> a -> m (Step s b)
step s
s a
a =
        if a -> Bool
cond a
a
        then do
            b
res <- s -> m b
pextract s
s
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
0 b
res
        else s -> a -> m (Step s b)
pstep s
s a
a

-- | See 'Streamly.Internal.Data.Parser.sliceBeginWith'.
--
-- /Pre-release/
--
data SliceBeginWithState s = Left' s | Right' s

{-# INLINE sliceBeginWith #-}
sliceBeginWith :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
sliceBeginWith :: forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
sliceBeginWith a -> Bool
cond (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) =

    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser SliceBeginWithState s -> a -> m (Step (SliceBeginWithState s) b)
step forall {b}. m (Initial (SliceBeginWithState s) b)
initial SliceBeginWithState s -> m b
extract

    where

    initial :: m (Initial (SliceBeginWithState s) b)
initial =  do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
            case Step s b
res of
                FL.Partial s
s -> forall s b. s -> Initial s b
IPartial (forall s. s -> SliceBeginWithState s
Left' s
s)
                FL.Done b
_ -> forall s b. String -> Initial s b
IError String
"sliceBeginWith : bad finitial"

    {-# INLINE process #-}
    process :: s -> a -> m (Step (SliceBeginWithState s) b)
process s
s a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall s. s -> SliceBeginWithState s
Right' s
s1)
                FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b

    step :: SliceBeginWithState s -> a -> m (Step (SliceBeginWithState s) b)
step (Left' s
s) a
a =
        if a -> Bool
cond a
a
        then s -> a -> m (Step (SliceBeginWithState s) b)
process s
s a
a
        else forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"sliceBeginWith : slice begins with an element which "
                        forall a. [a] -> [a] -> [a]
++ String
"fails the predicate"
    step (Right' s
s) a
a =
        if Bool -> Bool
not (a -> Bool
cond a
a)
        then s -> a -> m (Step (SliceBeginWithState s) b)
process s
s a
a
        else forall s b. Int -> b -> Step s b
Done Int
1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
s

    extract :: SliceBeginWithState s -> m b
extract (Left' s
s) = s -> m b
fextract s
s
    extract (Right' s
s) = s -> m b
fextract s
s

data WordByState s b = WBLeft !s | WBWord !s | WBRight !b

-- | See 'Streamly.Internal.Data.Parser.wordBy'.
--
--
{-# INLINE wordBy #-}
wordBy :: Monad m => (a -> Bool) -> Fold m a b -> Parser m a b
wordBy :: forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
wordBy a -> Bool
predicate (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser WordByState s b -> a -> m (Step (WordByState s b) b)
step forall {b}. m (Initial (WordByState s b) b)
initial WordByState s b -> m b
extract

    where

    {-# INLINE worder #-}
    worder :: s -> a -> m (Step (WordByState s b) b)
worder s
s a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall s b. s -> WordByState s b
WBWord s
s1
                  FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b

    initial :: m (Initial (WordByState s b) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall s b. s -> WordByState s b
WBLeft s
s
                  FL.Done b
b -> forall s b. b -> Initial s b
IDone b
b

    step :: WordByState s b -> a -> m (Step (WordByState s b) b)
step (WBLeft s
s) a
a =
        if Bool -> Bool
not (a -> Bool
predicate a
a)
        then forall {b}. s -> a -> m (Step (WordByState s b) b)
worder s
s a
a
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall s b. s -> WordByState s b
WBLeft s
s
    step (WBWord s
s) a
a =
        if Bool -> Bool
not (a -> Bool
predicate a
a)
        then forall {b}. s -> a -> m (Step (WordByState s b) b)
worder s
s a
a
        else do
            b
b <- s -> m b
fextract s
s
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall s b. b -> WordByState s b
WBRight b
b
    step (WBRight b
b) a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not (a -> Bool
predicate a
a)
              then forall s b. Int -> b -> Step s b
Done Int
1 b
b
              else forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall s b. b -> WordByState s b
WBRight b
b

    extract :: WordByState s b -> m b
extract (WBLeft s
s) = s -> m b
fextract s
s
    extract (WBWord s
s) = s -> m b
fextract s
s
    extract (WBRight b
b) = forall (m :: * -> *) a. Monad m => a -> m a
return b
b

{-# ANN type GroupByState Fuse #-}
data GroupByState a s
    = GroupByInit !s
    | GroupByGrouping !a !s

-- | See 'Streamly.Internal.Data.Parser.groupBy'.
--
{-# INLINE groupBy #-}
groupBy :: Monad m => (a -> a -> Bool) -> Fold m a b -> Parser m a b
groupBy :: forall (m :: * -> *) a b.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Parser m a b
groupBy a -> a -> Bool
eq (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser GroupByState a s -> a -> m (Step (GroupByState a s) b)
step forall {a}. m (Initial (GroupByState a s) b)
initial forall {a}. GroupByState a s -> m b
extract

    where

    {-# INLINE grouper #-}
    grouper :: s -> a -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a0 a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b
                  FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall a s. a -> s -> GroupByState a s
GroupByGrouping a
a0 s
s1)

    initial :: m (Initial (GroupByState a s) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a s. s -> GroupByState a s
GroupByInit s
s
                  FL.Done b
b -> forall s b. b -> Initial s b
IDone b
b

    step :: GroupByState a s -> a -> m (Step (GroupByState a s) b)
step (GroupByInit s
s) a
a = forall {a}. s -> a -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a a
a
    step (GroupByGrouping a
a0 s
s) a
a =
        if a -> a -> Bool
eq a
a0 a
a
        then forall {a}. s -> a -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a0 a
a
        else forall s b. Int -> b -> Step s b
Done Int
1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
s

    extract :: GroupByState a s -> m b
extract (GroupByInit s
s) = s -> m b
fextract s
s
    extract (GroupByGrouping a
_ s
s) = s -> m b
fextract s
s

-- | See 'Streamly.Internal.Data.Parser.groupByRolling'.
--
{-# INLINE groupByRolling #-}
groupByRolling :: Monad m => (a -> a -> Bool) -> Fold m a b -> Parser m a b
groupByRolling :: forall (m :: * -> *) a b.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Parser m a b
groupByRolling a -> a -> Bool
eq (Fold s -> a -> m (Step s b)
fstep m (Step s b)
finitial s -> m b
fextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser GroupByState a s -> a -> m (Step (GroupByState a s) b)
step forall {a}. m (Initial (GroupByState a s) b)
initial forall {a}. GroupByState a s -> m b
extract

    where

    {-# INLINE grouper #-}
    grouper :: s -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep s
s a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 b
b
                  FL.Partial s
s1 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall a s. a -> s -> GroupByState a s
GroupByGrouping a
a s
s1)

    initial :: m (Initial (GroupByState a s) b)
initial = do
        Step s b
res <- m (Step s b)
finitial
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                  FL.Partial s
s -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a s. s -> GroupByState a s
GroupByInit s
s
                  FL.Done b
b -> forall s b. b -> Initial s b
IDone b
b

    step :: GroupByState a s -> a -> m (Step (GroupByState a s) b)
step (GroupByInit s
s) a
a = s -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a
    step (GroupByGrouping a
a0 s
s) a
a =
        if a -> a -> Bool
eq a
a0 a
a
        then s -> a -> m (Step (GroupByState a s) b)
grouper s
s a
a
        else forall s b. Int -> b -> Step s b
Done Int
1 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract s
s

    extract :: GroupByState a s -> m b
extract (GroupByInit s
s) = s -> m b
fextract s
s
    extract (GroupByGrouping a
_ s
s) = s -> m b
fextract s
s

{-# ANN type GroupByStatePair Fuse #-}
data GroupByStatePair a s1 s2
    = GroupByInitPair !s1 !s2
    | GroupByGroupingPair !a !s1 !s2
    | GroupByGroupingPairL !a !s1 !s2
    | GroupByGroupingPairR !a !s1 !s2

{-# INLINE groupByRollingEither #-}
groupByRollingEither :: MonadCatch m =>
    (a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (Either b c)
groupByRollingEither :: forall (m :: * -> *) a b c.
MonadCatch m =>
(a -> a -> Bool)
-> Fold m a b -> Fold m a c -> Parser m a (Either b c)
groupByRollingEither
    a -> a -> Bool
eq
    (Fold s -> a -> m (Step s b)
fstep1 m (Step s b)
finitial1 s -> m b
fextract1)
    (Fold s -> a -> m (Step s c)
fstep2 m (Step s c)
finitial2 s -> m c
fextract2) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser GroupByStatePair a s s
-> a -> m (Step (GroupByStatePair a s s) (Either b c))
step forall {a}. m (Initial (GroupByStatePair a s s) (Either b c))
initial GroupByStatePair a s s -> m (Either b c)
extract

    where

    {-# INLINE grouper #-}
    grouper :: s1 -> s2 -> a -> m (Step (GroupByStatePair a s1 s2) b)
grouper s1
s1 s2
s2 a
a = do
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
0 (forall a s1 s2. a -> s1 -> s2 -> GroupByStatePair a s1 s2
GroupByGroupingPair a
a s1
s1 s2
s2)

    {-# INLINE grouperL2 #-}
    grouperL2 :: s -> s2 -> a -> m (Step (GroupByStatePair a s s2) (Either b b))
grouperL2 s
s1 s2
s2 a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep1 s
s1 a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res of
                FL.Done b
b -> forall s b. Int -> b -> Step s b
Done Int
0 (forall a b. a -> Either a b
Left b
b)
                FL.Partial s
s11 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall a s1 s2. a -> s1 -> s2 -> GroupByStatePair a s1 s2
GroupByGroupingPairL a
a s
s11 s2
s2)

    {-# INLINE grouperL #-}
    grouperL :: s
-> s2 -> a -> a -> m (Step (GroupByStatePair a s s2) (Either b b))
grouperL s
s1 s2
s2 a
a0 a
a = do
        Step s b
res <- s -> a -> m (Step s b)
fstep1 s
s1 a
a0
        case Step s b
res of
            FL.Done b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
0 (forall a b. a -> Either a b
Left b
b)
            FL.Partial s
s11 -> forall {s2} {b}.
s -> s2 -> a -> m (Step (GroupByStatePair a s s2) (Either b b))
grouperL2 s
s11 s2
s2 a
a

    {-# INLINE grouperR2 #-}
    grouperR2 :: s1 -> s -> a -> m (Step (GroupByStatePair a s1 s) (Either a c))
grouperR2 s1
s1 s
s2 a
a = do
        Step s c
res <- s -> a -> m (Step s c)
fstep2 s
s2 a
a
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s c
res of
                FL.Done c
b -> forall s b. Int -> b -> Step s b
Done Int
0 (forall a b. b -> Either a b
Right c
b)
                FL.Partial s
s21 -> forall s b. Int -> s -> Step s b
Partial Int
0 (forall a s1 s2. a -> s1 -> s2 -> GroupByStatePair a s1 s2
GroupByGroupingPairR a
a s1
s1 s
s21)

    {-# INLINE grouperR #-}
    grouperR :: s1
-> s -> a -> a -> m (Step (GroupByStatePair a s1 s) (Either a c))
grouperR s1
s1 s
s2 a
a0 a
a = do
        Step s c
res <- s -> a -> m (Step s c)
fstep2 s
s2 a
a0
        case Step s c
res of
            FL.Done c
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
0 (forall a b. b -> Either a b
Right c
b)
            FL.Partial s
s21 -> forall {s1} {a}.
s1 -> s -> a -> m (Step (GroupByStatePair a s1 s) (Either a c))
grouperR2 s1
s1 s
s21 a
a

    initial :: m (Initial (GroupByStatePair a s s) (Either b c))
initial = do
        Step s b
res1 <- m (Step s b)
finitial1
        Step s c
res2 <- m (Step s c)
finitial2
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
res1 of
                FL.Partial s
s1 ->
                    case Step s c
res2 of
                        FL.Partial s
s2 -> forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a s1 s2. s1 -> s2 -> GroupByStatePair a s1 s2
GroupByInitPair s
s1 s
s2
                        FL.Done c
b -> forall s b. b -> Initial s b
IDone (forall a b. b -> Either a b
Right c
b)
                FL.Done b
b -> forall s b. b -> Initial s b
IDone (forall a b. a -> Either a b
Left b
b)

    step :: GroupByStatePair a s s
-> a -> m (Step (GroupByStatePair a s s) (Either b c))
step (GroupByInitPair s
s1 s
s2) a
a = forall {m :: * -> *} {s1} {s2} {a} {b}.
Monad m =>
s1 -> s2 -> a -> m (Step (GroupByStatePair a s1 s2) b)
grouper s
s1 s
s2 a
a

    step (GroupByGroupingPair a
a0 s
s1 s
s2) a
a =
        if Bool -> Bool
not (a -> a -> Bool
eq a
a0 a
a)
        then forall {s2} {b}.
s
-> s2 -> a -> a -> m (Step (GroupByStatePair a s s2) (Either b b))
grouperL s
s1 s
s2 a
a0 a
a
        else forall {s1} {a}.
s1
-> s -> a -> a -> m (Step (GroupByStatePair a s1 s) (Either a c))
grouperR s
s1 s
s2 a
a0 a
a

    step (GroupByGroupingPairL a
a0 s
s1 s
s2) a
a =
        if Bool -> Bool
not (a -> a -> Bool
eq a
a0 a
a)
        then forall {s2} {b}.
s -> s2 -> a -> m (Step (GroupByStatePair a s s2) (Either b b))
grouperL2 s
s1 s
s2 a
a
        else forall s b. Int -> b -> Step s b
Done Int
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract1 s
s1

    step (GroupByGroupingPairR a
a0 s
s1 s
s2) a
a =
        if a -> a -> Bool
eq a
a0 a
a
        then forall {s1} {a}.
s1 -> s -> a -> m (Step (GroupByStatePair a s1 s) (Either a c))
grouperR2 s
s1 s
s2 a
a
        else forall s b. Int -> b -> Step s b
Done Int
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m c
fextract2 s
s2

    extract :: GroupByStatePair a s s -> m (Either b c)
extract (GroupByInitPair s
s1 s
_) = forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract1 s
s1
    extract (GroupByGroupingPairL a
_ s
s1 s
_) = forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract1 s
s1
    extract (GroupByGroupingPairR a
_ s
_ s
s2) = forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m c
fextract2 s
s2
    extract (GroupByGroupingPair a
a s
s1 s
_) = do
                Step s b
res <- s -> a -> m (Step s b)
fstep1 s
s1 a
a
                case Step s b
res of
                    FL.Done b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left b
b
                    FL.Partial s
s11 -> forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
fextract1 s
s11

-- XXX use an Unfold instead of a list?
-- XXX custom combinators for matching list, array and stream?
--
-- | See 'Streamly.Internal.Data.Parser.eqBy'.
--
-- /Pre-release/
--
{-# INLINE eqBy #-}
eqBy :: MonadThrow m => (a -> a -> Bool) -> [a] -> Parser m a ()
eqBy :: forall (m :: * -> *) a.
MonadThrow m =>
(a -> a -> Bool) -> [a] -> Parser m a ()
eqBy a -> a -> Bool
cmp [a]
str = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser forall {m :: * -> *}. Monad m => [a] -> a -> m (Step [a] ())
step forall {b}. m (Initial [a] b)
initial forall {m :: * -> *} {t :: * -> *} {a} {a}.
(MonadThrow m, Foldable t) =>
t a -> m a
extract

    where

    initial :: m (Initial [a] b)
initial = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial [a]
str

    step :: [a] -> a -> m (Step [a] ())
step [] a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
0 ()
    step [a
x] a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ if a
x a -> a -> Bool
`cmp` a
a
              then forall s b. Int -> b -> Step s b
Done Int
0 ()
              else forall s b. String -> Step s b
Error String
"eqBy: failed, yet to match the last element"
    step (a
x:[a]
xs) a
a =
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ if a
x a -> a -> Bool
`cmp` a
a
              then forall s b. Int -> s -> Step s b
Continue Int
0 [a]
xs
              else forall s b. String -> Step s b
Error
                       forall a b. (a -> b) -> a -> b
$ String
"eqBy: failed, yet to match "
                       forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs forall a. Num a => a -> a -> a
+ Int
1) forall a. [a] -> [a] -> [a]
++ String
" elements"

    extract :: t a -> m a
extract t a
xs =
        forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
            forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError
            forall a b. (a -> b) -> a -> b
$ String
"eqBy: end of input, yet to match "
            forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show (forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
xs) forall a. [a] -> [a] -> [a]
++ String
" elements"

--------------------------------------------------------------------------------
--- Spanning
--------------------------------------------------------------------------------

-- | @span p f1 f2@ composes folds @f1@ and @f2@ such that @f1@ consumes the
-- input as long as the predicate @p@ is 'True'.  @f2@ consumes the rest of the
-- input.
--
-- @
-- > let span_ p xs = Stream.parse (Parser.span p Fold.toList Fold.toList) $ Stream.fromList xs
--
-- > span_ (< 1) [1,2,3]
-- ([],[1,2,3])
--
-- > span_ (< 2) [1,2,3]
-- ([1],[2,3])
--
-- > span_ (< 4) [1,2,3]
-- ([1,2,3],[])
--
-- @
--
-- /Pre-release/
{-# INLINE span #-}
span :: Monad m => (a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
span :: forall (m :: * -> *) a b c.
Monad m =>
(a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
span a -> Bool
p Fold m a b
f1 Fold m a c
f2 = forall (m :: * -> *) a b c x.
Monad m =>
(a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
noErrorUnsafeSplitWith (,) (forall (m :: * -> *) a b.
Monad m =>
(a -> Bool) -> Fold m a b -> Parser m a b
takeWhile a -> Bool
p Fold m a b
f1) (forall (m :: * -> *) a b. Monad m => Fold m a b -> Parser m a b
fromFold Fold m a c
f2)

-- | Break the input stream into two groups, the first group takes the input as
-- long as the predicate applied to the first element of the stream and next
-- input element holds 'True', the second group takes the rest of the input.
--
-- /Pre-release/
--
{-# INLINE spanBy #-}
spanBy ::
       Monad m
    => (a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
spanBy :: forall (m :: * -> *) a b c.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
spanBy a -> a -> Bool
eq Fold m a b
f1 Fold m a c
f2 = forall (m :: * -> *) a b c x.
Monad m =>
(a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
noErrorUnsafeSplitWith (,) (forall (m :: * -> *) a b.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Parser m a b
groupBy a -> a -> Bool
eq Fold m a b
f1) (forall (m :: * -> *) a b. Monad m => Fold m a b -> Parser m a b
fromFold Fold m a c
f2)

-- | Like 'spanBy' but applies the predicate in a rolling fashion i.e.
-- predicate is applied to the previous and the next input elements.
--
-- /Pre-release/
{-# INLINE spanByRolling #-}
spanByRolling ::
       Monad m
    => (a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
spanByRolling :: forall (m :: * -> *) a b c.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Fold m a c -> Parser m a (b, c)
spanByRolling a -> a -> Bool
eq Fold m a b
f1 Fold m a c
f2 =
    forall (m :: * -> *) a b c x.
Monad m =>
(a -> b -> c) -> Parser m x a -> Parser m x b -> Parser m x c
noErrorUnsafeSplitWith (,) (forall (m :: * -> *) a b.
Monad m =>
(a -> a -> Bool) -> Fold m a b -> Parser m a b
groupByRolling a -> a -> Bool
eq Fold m a b
f1) (forall (m :: * -> *) a b. Monad m => Fold m a b -> Parser m a b
fromFold Fold m a c
f2)

-------------------------------------------------------------------------------
-- nested parsers
-------------------------------------------------------------------------------

-- | See 'Streamly.Internal.Data.Parser.takeP'.
--
-- /Internal/
{-# INLINE takeP #-}
takeP :: Monad m => Int -> Parser m a b -> Parser m a b
takeP :: forall (m :: * -> *) a b.
Monad m =>
Int -> Parser m a b -> Parser m a b
takeP Int
lim (Parser s -> a -> m (Step s b)
pstep m (Initial s b)
pinitial s -> m b
pextract) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step m (Initial (Tuple' Int s) b)
initial forall {a}. Tuple' a s -> m b
extract

    where

    initial :: m (Initial (Tuple' Int s) b)
initial = do
        Initial s b
res <- m (Initial s b)
pinitial
        case Initial s b
res of
            IPartial s
s ->
                if Int
lim forall a. Ord a => a -> a -> Bool
> Int
0
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. s -> Initial s b
IPartial forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
0 s
s
                else forall s b. b -> Initial s b
IDone forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
pextract s
s
            IDone b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Initial s b
IDone b
b
            IError String
e -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Initial s b
IError String
e

    step :: Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step (Tuple' Int
cnt s
r) a
a = do
        forall a. HasCallStack => Bool -> a -> a
assert (Int
cnt forall a. Ord a => a -> a -> Bool
< Int
lim) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
        Step s b
res <- s -> a -> m (Step s b)
pstep s
r a
a
        let cnt1 :: Int
cnt1 = Int
cnt forall a. Num a => a -> a -> a
+ Int
1
        case Step s b
res of
            Partial Int
0 s
s -> do
                forall a. HasCallStack => Bool -> a -> a
assert (Int
cnt1 forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                if Int
cnt1 forall a. Ord a => a -> a -> Bool
< Int
lim
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
0 forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
cnt1 s
s
                else forall s b. Int -> b -> Step s b
Done Int
0 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
pextract s
s
            Continue Int
0 s
s -> do
                forall a. HasCallStack => Bool -> a -> a
assert (Int
cnt1 forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                if Int
cnt1 forall a. Ord a => a -> a -> Bool
< Int
lim
                then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
0 forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
cnt1 s
s
                -- XXX This should error out?
                -- If designed properly, this will probably error out.
                -- "pextract" should error out
                --
                -- By Harendra,
                --
                -- This is a tricky case, we have the following options:
                --   1. Done 0 with extract as you have written
                --   2. Done n, will require buffering elements
                --   3. Use a backtracking fold and not a parser, once we have
                --      backtracking in folds
                else forall s b. Int -> b -> Step s b
Done Int
0 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m b
pextract s
s
            Partial Int
n s
s -> do
                let taken :: Int
taken = Int
cnt1 forall a. Num a => a -> a -> a
- Int
n
                forall a. HasCallStack => Bool -> a -> a
assert (Int
taken forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
n forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
taken s
s
            Continue Int
n s
s -> do
                let taken :: Int
taken = Int
cnt1 forall a. Num a => a -> a -> a
- Int
n
                forall a. HasCallStack => Bool -> a -> a
assert (Int
taken forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
n forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> Tuple' a b
Tuple' Int
taken s
s
            Done Int
n b
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
n b
b
            Error String
str -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
Error String
str

    extract :: Tuple' a s -> m b
extract (Tuple' a
_ s
r) = s -> m b
pextract s
r

-- | See 'Streamly.Internal.Data.Parser.lookahead'.
--
-- /Pre-release/
--
{-# INLINE lookAhead #-}
lookAhead :: MonadThrow m => Parser m a b -> Parser m a b
lookAhead :: forall (m :: * -> *) a b.
MonadThrow m =>
Parser m a b -> Parser m a b
lookAhead (Parser s -> a -> m (Step s b)
step1 m (Initial s b)
initial1 s -> m b
_) = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step m (Initial (Tuple' Int s) b)
initial forall {m :: * -> *} {a} {b} {a}.
(MonadThrow m, Show a) =>
Tuple' a b -> m a
extract

    where

    initial :: m (Initial (Tuple' Int s) b)
initial = do
        Initial s b
res <- m (Initial s b)
initial1
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Initial s b
res of
            IPartial s
s -> forall s b. s -> Initial s b
IPartial (forall a b. a -> b -> Tuple' a b
Tuple' Int
0 s
s)
            IDone b
b -> forall s b. b -> Initial s b
IDone b
b
            IError String
e -> forall s b. String -> Initial s b
IError String
e

    step :: Tuple' Int s -> a -> m (Step (Tuple' Int s) b)
step (Tuple' Int
cnt s
st) a
a = do
        Step s b
r <- s -> a -> m (Step s b)
step1 s
st a
a
        let cnt1 :: Int
cnt1 = Int
cnt forall a. Num a => a -> a -> a
+ Int
1
        forall (m :: * -> *) a. Monad m => a -> m a
return
            forall a b. (a -> b) -> a -> b
$ case Step s b
r of
                  Partial Int
n s
s -> forall s b. Int -> s -> Step s b
Continue Int
n (forall a b. a -> b -> Tuple' a b
Tuple' (Int
cnt1 forall a. Num a => a -> a -> a
- Int
n) s
s)
                  Continue Int
n s
s -> forall s b. Int -> s -> Step s b
Continue Int
n (forall a b. a -> b -> Tuple' a b
Tuple' (Int
cnt1 forall a. Num a => a -> a -> a
- Int
n) s
s)
                  Done Int
_ b
b -> forall s b. Int -> b -> Step s b
Done Int
cnt1 b
b
                  Error String
err -> forall s b. String -> Step s b
Error String
err

    -- XXX returning an error let's us backtrack.  To implement it in a way so
    -- that it terminates on eof without an error then we need a way to
    -- backtrack on eof, that will require extract to return 'Step' type.
    extract :: Tuple' a b -> m a
extract (Tuple' a
n b
_) =
        forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
            forall a b. (a -> b) -> a -> b
$ String -> ParseError
ParseError
            forall a b. (a -> b) -> a -> b
$ String
"lookAhead: end of input after consuming "
            forall a. [a] -> [a] -> [a]
++ forall {a}. Show a => a -> String
show a
n forall a. [a] -> [a] -> [a]
++ String
" elements"

-------------------------------------------------------------------------------
-- Interleaving
-------------------------------------------------------------------------------
--
-- | See 'Streamly.Internal.Data.Parser.deintercalate'.
--
-- /Unimplemented/
--
{-# INLINE deintercalate #-}
deintercalate ::
    -- Monad m =>
       Fold m a y -> Parser m x a
    -> Fold m b z -> Parser m x b
    -> Parser m x (y, z)
deintercalate :: forall (m :: * -> *) a y x b z.
Fold m a y
-> Parser m x a -> Fold m b z -> Parser m x b -> Parser m x (y, z)
deintercalate = forall a. HasCallStack => a
undefined

-------------------------------------------------------------------------------
-- Sequential Collection
-------------------------------------------------------------------------------
--
-- | See 'Streamly.Internal.Data.Parser.sequence'.
--
-- /Unimplemented/
--
{-# INLINE sequence #-}
sequence ::
    -- Foldable t =>
    Fold m b c -> t (Parser m a b) -> Parser m a c
sequence :: forall (m :: * -> *) b c (t :: * -> *) a.
Fold m b c -> t (Parser m a b) -> Parser m a c
sequence Fold m b c
_f t (Parser m a b)
_p = forall a. HasCallStack => a
undefined

-------------------------------------------------------------------------------
-- Alternative Collection
-------------------------------------------------------------------------------

-- | See 'Streamly.Internal.Data.Parser.choice'.
--
-- /Broken/
--
{-# INLINE choice #-}
choice :: (MonadCatch m, Foldable t) => t (Parser m a b) -> Parser m a b
choice :: forall (m :: * -> *) (t :: * -> *) a b.
(MonadCatch m, Foldable t) =>
t (Parser m a b) -> Parser m a b
choice = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 forall (m :: * -> *) x a.
Monad m =>
Parser m x a -> Parser m x a -> Parser m x a
shortest

-------------------------------------------------------------------------------
-- Sequential Repetition
-------------------------------------------------------------------------------
--
-- | See 'Streamly.Internal.Data.Parser.many'.
--
-- /Pre-release/
--
{-# INLINE many #-}
many :: MonadCatch m => Parser m a b -> Fold m b c -> Parser m a c
many :: forall (m :: * -> *) a b c.
MonadCatch m =>
Parser m a b -> Fold m b c -> Parser m a c
many = forall (m :: * -> *) a b c.
MonadCatch m =>
Parser m a b -> Fold m b c -> Parser m a c
splitMany
-- many = countBetween 0 maxBound

-- | See 'Streamly.Internal.Data.Parser.some'.
--
-- /Pre-release/
--
{-# INLINE some #-}
some :: MonadCatch m => Parser m a b -> Fold m b c -> Parser m a c
some :: forall (m :: * -> *) a b c.
MonadCatch m =>
Parser m a b -> Fold m b c -> Parser m a c
some = forall (m :: * -> *) a b c.
MonadCatch m =>
Parser m a b -> Fold m b c -> Parser m a c
splitSome
-- some f p = many (takeGE 1 f) p
-- many = countBetween 1 maxBound

-- | See 'Streamly.Internal.Data.Parser.countBetween'.
--
-- /Unimplemented/
--
{-# INLINE countBetween #-}
countBetween ::
    -- MonadCatch m =>
    Int -> Int -> Parser m a b -> Fold m b c -> Parser m a c
countBetween :: forall (m :: * -> *) a b c.
Int -> Int -> Parser m a b -> Fold m b c -> Parser m a c
countBetween Int
_m Int
_n Parser m a b
_p = forall a. HasCallStack => a
undefined
-- countBetween m n p f = many (takeBetween m n f) p

-- | See 'Streamly.Internal.Data.Parser.count'.
--
-- /Unimplemented/
--
{-# INLINE count #-}
count ::
    -- MonadCatch m =>
    Int -> Parser m a b -> Fold m b c -> Parser m a c
count :: forall (m :: * -> *) a b c.
Int -> Parser m a b -> Fold m b c -> Parser m a c
count Int
n = forall (m :: * -> *) a b c.
Int -> Int -> Parser m a b -> Fold m b c -> Parser m a c
countBetween Int
n Int
n
-- count n f p = many (takeEQ n f) p

data ManyTillState fs sr sl
    = ManyTillR Int fs sr
    | ManyTillL Int fs sl

-- | See 'Streamly.Internal.Data.Parser.manyTill'.
--
-- /Pre-release/
--
{-# INLINE manyTill #-}
manyTill :: MonadCatch m
    => Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
manyTill :: forall (m :: * -> *) b c a x.
MonadCatch m =>
Fold m b c -> Parser m a b -> Parser m a x -> Parser m a c
manyTill (Fold s -> b -> m (Step s c)
fstep m (Step s c)
finitial s -> m c
fextract)
         (Parser s -> a -> m (Step s b)
stepL m (Initial s b)
initialL s -> m b
extractL)
         (Parser s -> a -> m (Step s x)
stepR m (Initial s x)
initialR s -> m x
_) =
    forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Initial s b) -> (s -> m b) -> Parser m a b
Parser ManyTillState s s s -> a -> m (Step (ManyTillState s s s) c)
step m (Initial (ManyTillState s s s) c)
initial forall {sr}. ManyTillState s sr s -> m c
extract

    where

    -- Caution: Mutual recursion

    scrutL :: s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutL s
fs ManyTillState s s sl -> b
p ManyTillState s sr s -> b
c c -> b
d String -> b
e = do
        Initial s b
resL <- m (Initial s b)
initialL
        case Initial s b
resL of
            IPartial s
sl -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ManyTillState s sr s -> b
c (forall fs sr sl. Int -> fs -> sl -> ManyTillState fs sr sl
ManyTillL Int
0 s
fs s
sl)
            IDone b
bl -> do
                Step s c
fr <- s -> b -> m (Step s c)
fstep s
fs b
bl
                case Step s c
fr of
                    FL.Partial s
fs1 -> s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutR s
fs1 ManyTillState s s sl -> b
p ManyTillState s sr s -> b
c c -> b
d String -> b
e
                    FL.Done c
fb -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ c -> b
d c
fb
            IError String
err -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String -> b
e String
err

    scrutR :: s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutR s
fs ManyTillState s s sl -> b
p ManyTillState s sr s -> b
c c -> b
d String -> b
e = do
        Initial s x
resR <- m (Initial s x)
initialR
        case Initial s x
resR of
            IPartial s
sr -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ManyTillState s s sl -> b
p (forall fs sr sl. Int -> fs -> sr -> ManyTillState fs sr sl
ManyTillR Int
0 s
fs s
sr)
            IDone x
_ -> c -> b
d forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> s -> m c
fextract s
fs
            IError String
_ -> s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutL s
fs ManyTillState s s sl -> b
p ManyTillState s sr s -> b
c c -> b
d String -> b
e

    initial :: m (Initial (ManyTillState s s s) c)
initial = do
        Step s c
res <- m (Step s c)
finitial
        case Step s c
res of
            FL.Partial s
fs -> forall {sl} {b} {sr}.
s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutR s
fs forall s b. s -> Initial s b
IPartial forall s b. s -> Initial s b
IPartial forall s b. b -> Initial s b
IDone forall s b. String -> Initial s b
IError
            FL.Done c
b -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. b -> Initial s b
IDone c
b

    step :: ManyTillState s s s -> a -> m (Step (ManyTillState s s s) c)
step (ManyTillR Int
cnt s
fs s
st) a
a = do
        Step s x
r <- s -> a -> m (Step s x)
stepR s
st a
a
        case Step s x
r of
            Partial Int
n s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
n (forall fs sr sl. Int -> fs -> sr -> ManyTillState fs sr sl
ManyTillR Int
0 s
fs s
s)
            Continue Int
n s
s -> do
                forall a. HasCallStack => Bool -> a -> a
assert (Int
cnt forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
- Int
n forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
n (forall fs sr sl. Int -> fs -> sr -> ManyTillState fs sr sl
ManyTillR (Int
cnt forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
- Int
n) s
fs s
s)
            Done Int
n x
_ -> do
                c
b <- s -> m c
fextract s
fs
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
n c
b
            Error String
_ -> do
                Initial s b
resL <- m (Initial s b)
initialL
                case Initial s b
resL of
                    IPartial s
sl ->
                        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue (Int
cnt forall a. Num a => a -> a -> a
+ Int
1) (forall fs sr sl. Int -> fs -> sl -> ManyTillState fs sr sl
ManyTillL Int
0 s
fs s
sl)
                    IDone b
bl -> do
                        Step s c
fr <- s -> b -> m (Step s c)
fstep s
fs b
bl
                        let cnt1 :: Int
cnt1 = Int
cnt forall a. Num a => a -> a -> a
+ Int
1
                            p :: s -> Step s b
p = forall s b. Int -> s -> Step s b
Partial Int
cnt
                            c :: s -> Step s b
c = forall s b. Int -> s -> Step s b
Continue Int
cnt
                            d :: b -> Step s b
d = forall s b. Int -> b -> Step s b
Done Int
cnt
                        case Step s c
fr of
                            FL.Partial s
fs1 -> forall {sl} {b} {sr}.
s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutR s
fs1 forall {s} {b}. s -> Step s b
p forall {s} {b}. s -> Step s b
c forall {b} {s}. b -> Step s b
d forall s b. String -> Step s b
Error
                            FL.Done c
fb -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
cnt1 c
fb
                    IError String
err -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
Error String
err
    -- XXX the cnt is being used only by the assert
    step (ManyTillL Int
cnt s
fs s
st) a
a = do
        Step s b
r <- s -> a -> m (Step s b)
stepL s
st a
a
        case Step s b
r of
            Partial Int
n s
s -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Partial Int
n (forall fs sr sl. Int -> fs -> sl -> ManyTillState fs sr sl
ManyTillL Int
0 s
fs s
s)
            Continue Int
n s
s -> do
                forall a. HasCallStack => Bool -> a -> a
assert (Int
cnt forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
- Int
n forall a. Ord a => a -> a -> Bool
>= Int
0) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
                forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> s -> Step s b
Continue Int
n (forall fs sr sl. Int -> fs -> sl -> ManyTillState fs sr sl
ManyTillL (Int
cnt forall a. Num a => a -> a -> a
+ Int
1 forall a. Num a => a -> a -> a
- Int
n) s
fs s
s)
            Done Int
n b
b -> do
                Step s c
fs1 <- s -> b -> m (Step s c)
fstep s
fs b
b
                case Step s c
fs1 of
                    FL.Partial s
s ->
                        forall {sl} {b} {sr}.
s
-> (ManyTillState s s sl -> b)
-> (ManyTillState s sr s -> b)
-> (c -> b)
-> (String -> b)
-> m b
scrutR s
s (forall s b. Int -> s -> Step s b
Partial Int
n) (forall s b. Int -> s -> Step s b
Continue Int
n) (forall s b. Int -> b -> Step s b
Done Int
n) forall s b. String -> Step s b
Error
                    FL.Done c
b1 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. Int -> b -> Step s b
Done Int
n c
b1
            Error String
err -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s b. String -> Step s b
Error String
err

    extract :: ManyTillState s sr s -> m c
extract (ManyTillL Int
_ s
fs s
sR) = do
        Step s c
res <- s -> m b
extractL s
sR forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= s -> b -> m (Step s c)
fstep s
fs
        case Step s c
res of
            FL.Partial s
s -> s -> m c
fextract s
s
            FL.Done c
b -> forall (m :: * -> *) a. Monad m => a -> m a
return c
b
    extract (ManyTillR Int
_ s
fs sr
_) = s -> m c
fextract s
fs