-- |
-- Module      : Foundation.Parser
-- License     : BSD-style
-- Maintainer  : Haskell Foundation
-- Stability   : experimental
-- Portability : portable
--
-- The current implementation is mainly, if not copy/pasted, inspired from
-- `memory`'s Parser.
--
-- Foundation Parser makes use of the Foundation's @Collection@ and
-- @Sequential@ classes to allow you to define generic parsers over any
-- @Sequential@ of inpu.
--
-- This way you can easily implements parsers over @LString@, @String@.
--
--
-- > flip parseOnly "my.email@address.com" $ do
-- >    EmailAddress
-- >      <$> (takeWhile ((/=) '@' <*  element '@')
-- >      <*> takeAll
--

{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}

module Foundation.Parser
    ( Parser
    , parse
    , parseFeed
    , parseOnly
    , -- * Result
      Result(..)
    , ParseError(..)
    , reportError

    , -- * Parser source
      ParserSource(..)

    , -- * combinator
      peek
    , element
    , anyElement
    , elements
    , string

    , satisfy
    , satisfy_
    , take
    , takeWhile
    , takeAll

    , skip
    , skipWhile
    , skipAll

    , (<|>)
    , many
    , some
    , optional
    , repeat, Condition(..), And(..)
    ) where

import           Control.Applicative (Alternative, empty, (<|>), many, some, optional)
import           Control.Monad (MonadPlus, mzero, mplus)

import           Basement.Compat.Base
import           Basement.Types.OffsetSize
import           Foundation.Numerical
import           Foundation.Collection hiding (take, takeWhile)
import qualified Foundation.Collection as C
import           Foundation.String

-- Error handling -------------------------------------------------------------

-- | common parser error definition
data ParseError input
    = NotEnough (CountOf (Element input))
        -- ^ meaning the parser was short of @CountOf@ @Element@ of `input`.
    | NotEnoughParseOnly
        -- ^ The parser needed more data, only when using @parseOnly@
    | ExpectedElement (Element input) (Element input)
        -- ^ when using @element@
    | Expected (Chunk input) (Chunk input)
        -- ^ when using @elements@ or @string@
    | Satisfy (Maybe String)
        -- ^ the @satisfy@ or @satisfy_@ function failed,
  deriving (Typeable)
instance (Typeable input, Show input) => Exception (ParseError input)

instance Show input => Show (ParseError input) where
    show :: ParseError input -> String
show (NotEnough (CountOf Int
sz)) = String
"NotEnough: missing " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
sz String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" element(s)"
    show ParseError input
NotEnoughParseOnly    = String
"NotEnough, parse only"
    show (ExpectedElement Element input
_ Element input
_) = String
"Expected _ but received _"
    show (Expected Chunk input
_ Chunk input
_)        = String
"Expected _ but received _"
    show (Satisfy Maybe String
Nothing)     = String
"Satisfy"
    show (Satisfy (Just String
s))    = String
"Satisfy: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String -> [Item String]
forall l. IsList l => l -> [Item l]
toList String
s

instance {-# OVERLAPPING #-} Show (ParseError String) where
    show :: ParseError String -> String
show (NotEnough (CountOf Int
sz)) = String
"NotEnough: missing " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
sz String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" element(s)"
    show ParseError String
NotEnoughParseOnly    = String
"NotEnough, parse only"
    show (ExpectedElement Element String
a Element String
b) = String
"Expected "String -> ShowS
forall a. Semigroup a => a -> a -> a
<>Char -> String
forall a. Show a => a -> String
show Char
Element String
aString -> ShowS
forall a. Semigroup a => a -> a -> a
<>String
" but received " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Char -> String
forall a. Show a => a -> String
show Char
Element String
b
    show (Expected Chunk String
a Chunk String
b)        = String
"Expected "String -> ShowS
forall a. Semigroup a => a -> a -> a
<>String -> String
forall a. Show a => a -> String
show String
Chunk String
aString -> ShowS
forall a. Semigroup a => a -> a -> a
<>String
" but received " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String -> String
forall a. Show a => a -> String
show String
Chunk String
b
    show (Satisfy Maybe String
Nothing)     = String
"Satisfy"
    show (Satisfy (Just String
s))    = String
"Satisfy: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String -> [Item String]
forall l. IsList l => l -> [Item l]
toList String
s

-- Results --------------------------------------------------------------------

-- | result of executing the `parser` over the given `input`
data Result input result
    = ParseFailed (ParseError input)
        -- ^ the parser failed with the given @ParserError@
    | ParseOk     (Chunk input) result
        -- ^ the parser complete successfuly with the remaining @Chunk@
    | ParseMore   (Chunk input -> Result input result)
        -- ^ the parser needs more input, pass an empty @Chunk@ or @mempty@
        -- to tell the parser you don't have anymore inputs.

instance (Show k, Show input) => Show (Result input k) where
    show :: Result input k -> String
show (ParseFailed ParseError input
err) = String
"Parser failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ParseError input -> String
forall a. Show a => a -> String
show ParseError input
err
    show (ParseOk Chunk input
_ k
k) = String
"Parser succeed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> k -> String
forall a. Show a => a -> String
show k
k
    show (ParseMore Chunk input -> Result input k
_) = String
"Parser incomplete: need more"
instance Functor (Result input) where
    fmap :: forall a b. (a -> b) -> Result input a -> Result input b
fmap a -> b
f Result input a
r = case Result input a
r of
        ParseFailed ParseError input
err -> ParseError input -> Result input b
forall input result. ParseError input -> Result input result
ParseFailed ParseError input
err
        ParseOk Chunk input
rest a
a  -> Chunk input -> b -> Result input b
forall input result. Chunk input -> result -> Result input result
ParseOk Chunk input
rest (a -> b
f a
a)
        ParseMore Chunk input -> Result input a
more -> (Chunk input -> Result input b) -> Result input b
forall input result.
(Chunk input -> Result input result) -> Result input result
ParseMore ((a -> b) -> Result input a -> Result input b
forall a b. (a -> b) -> Result input a -> Result input b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (Result input a -> Result input b)
-> (Chunk input -> Result input a) -> Chunk input -> Result input b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Chunk input -> Result input a
more)

-- Parser Source --------------------------------------------------------------

class (Sequential input, IndexedCollection input) => ParserSource input where
    type Chunk input

    nullChunk :: input -> Chunk input -> Bool

    appendChunk :: input -> Chunk input -> input

    subChunk :: input -> Offset (Element input) -> CountOf (Element input) -> Chunk input

    spanChunk :: input -> Offset (Element input) -> (Element input -> Bool) -> (Chunk input, Offset (Element input))

endOfParserSource :: ParserSource input => input -> Offset (Element input) -> Bool
endOfParserSource :: forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
l Offset (Element input)
off = Offset (Element input)
off Offset (Element input) -> CountOf (Element input) -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
l
{-# INLINE endOfParserSource #-}

-- Parser ---------------------------------------------------------------------

data NoMore = More | NoMore
  deriving (Int -> NoMore -> ShowS
[NoMore] -> ShowS
NoMore -> String
(Int -> NoMore -> ShowS)
-> (NoMore -> String) -> ([NoMore] -> ShowS) -> Show NoMore
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NoMore -> ShowS
showsPrec :: Int -> NoMore -> ShowS
$cshow :: NoMore -> String
show :: NoMore -> String
$cshowList :: [NoMore] -> ShowS
showList :: [NoMore] -> ShowS
Show, NoMore -> NoMore -> Bool
(NoMore -> NoMore -> Bool)
-> (NoMore -> NoMore -> Bool) -> Eq NoMore
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NoMore -> NoMore -> Bool
== :: NoMore -> NoMore -> Bool
$c/= :: NoMore -> NoMore -> Bool
/= :: NoMore -> NoMore -> Bool
Eq)

type Failure input         result = input -> Offset (Element input) -> NoMore -> ParseError input -> Result input result

type Success input result' result = input -> Offset (Element input) -> NoMore -> result'          -> Result input result

-- | Foundation's @Parser@ monad.
--
-- Its implementation is based on the parser in `memory`.
newtype Parser input result = Parser
    { forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser :: forall result'
                 . input -> Offset (Element input) -> NoMore
                -> Failure input        result'
                -> Success input result result'
                -> Result input result'
    }

instance Functor (Parser input) where
    fmap :: forall a b. (a -> b) -> Parser input a -> Parser input b
fmap a -> b
f Parser input a
fa = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input b result'
 -> Result input result')
-> Parser input b
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input b result'
  -> Result input result')
 -> Parser input b)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input b result'
    -> Result input result')
-> Parser input b
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input b result'
ok ->
        Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input a
fa input
buf Offset (Element input)
off NoMore
nm Failure input result'
err ((input
  -> Offset (Element input) -> NoMore -> a -> Result input result')
 -> Result input result')
-> (input
    -> Offset (Element input) -> NoMore -> a -> Result input result')
-> Result input result'
forall a b. (a -> b) -> a -> b
$ \input
buf' Offset (Element input)
off' NoMore
nm' a
a -> Success input b result'
ok input
buf' Offset (Element input)
off' NoMore
nm' (a -> b
f a
a)
    {-# INLINE fmap #-}

instance ParserSource input => Applicative (Parser input) where
    pure :: forall a. a -> Parser input a
pure a
a = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input a result'
 -> Result input result')
-> Parser input a
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input a result'
  -> Result input result')
 -> Parser input a)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input a result'
    -> Result input result')
-> Parser input a
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
_ Success input a result'
ok -> Success input a result'
ok input
buf Offset (Element input)
off NoMore
nm a
a
    {-# INLINE pure #-}
    Parser input (a -> b)
fab <*> :: forall a b.
Parser input (a -> b) -> Parser input a -> Parser input b
<*> Parser input a
fa = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input b result'
 -> Result input result')
-> Parser input b
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input b result'
  -> Result input result')
 -> Parser input b)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input b result'
    -> Result input result')
-> Parser input b
forall a b. (a -> b) -> a -> b
$ \input
buf0 Offset (Element input)
off0 NoMore
nm0 Failure input result'
err Success input b result'
ok ->
        Parser input (a -> b)
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input (a -> b) result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser  Parser input (a -> b)
fab input
buf0 Offset (Element input)
off0 NoMore
nm0 Failure input result'
err ((input
  -> Offset (Element input)
  -> NoMore
  -> (a -> b)
  -> Result input result')
 -> Result input result')
-> (input
    -> Offset (Element input)
    -> NoMore
    -> (a -> b)
    -> Result input result')
-> Result input result'
forall a b. (a -> b) -> a -> b
$ \input
buf1 Offset (Element input)
off1 NoMore
nm1 a -> b
ab ->
        Parser input a
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> (input
    -> Offset (Element input) -> NoMore -> a -> Result input result')
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ Parser input a
fa  input
buf1 Offset (Element input)
off1 NoMore
nm1 Failure input result'
err ((input
  -> Offset (Element input) -> NoMore -> a -> Result input result')
 -> Result input result')
-> (input
    -> Offset (Element input) -> NoMore -> a -> Result input result')
-> Result input result'
forall a b. (a -> b) -> a -> b
$ \input
buf2 Offset (Element input)
off2 NoMore
nm2 -> Success input b result'
ok input
buf2 Offset (Element input)
off2 NoMore
nm2 (b -> Result input result')
-> (a -> b) -> a -> Result input result'
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
ab
    {-# INLINE (<*>) #-}

instance ParserSource input => Monad (Parser input) where
    return :: forall a. a -> Parser input a
return = a -> Parser input a
forall a. a -> Parser input a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    {-# INLINE return #-}
    Parser input a
m >>= :: forall a b.
Parser input a -> (a -> Parser input b) -> Parser input b
>>= a -> Parser input b
k       = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input b result'
 -> Result input result')
-> Parser input b
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input b result'
  -> Result input result')
 -> Parser input b)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input b result'
    -> Result input result')
-> Parser input b
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input b result'
ok ->
        Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser  Parser input a
m     input
buf  Offset (Element input)
off  NoMore
nm  Failure input result'
err ((input
  -> Offset (Element input) -> NoMore -> a -> Result input result')
 -> Result input result')
-> (input
    -> Offset (Element input) -> NoMore -> a -> Result input result')
-> Result input result'
forall a b. (a -> b) -> a -> b
$ \input
buf' Offset (Element input)
off' NoMore
nm' a
a ->
        Parser input b
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input b result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ (a -> Parser input b
k a
a) input
buf' Offset (Element input)
off' NoMore
nm' Failure input result'
err Success input b result'
ok
    {-# INLINE (>>=) #-}

instance ParserSource input => MonadPlus (Parser input) where
    mzero :: forall a. Parser input a
mzero = String -> Parser input a
forall a. HasCallStack => String -> a
error String
"Foundation.Parser.Internal.MonadPlus.mzero"
    mplus :: forall a. Parser input a -> Parser input a -> Parser input a
mplus Parser input a
f Parser input a
g = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input a result'
 -> Result input result')
-> Parser input a
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input a result'
  -> Result input result')
 -> Parser input a)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input a result'
    -> Result input result')
-> Parser input a
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input a result'
ok ->
        Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input a
f input
buf Offset (Element input)
off NoMore
nm (\input
buf' Offset (Element input)
_ NoMore
nm' ParseError input
_ -> Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input a
g input
buf' Offset (Element input)
off NoMore
nm' Failure input result'
err Success input a result'
ok) Success input a result'
ok
    {-# INLINE mplus #-}
instance ParserSource input => Alternative (Parser input) where
    empty :: forall a. Parser input a
empty = String -> Parser input a
forall a. HasCallStack => String -> a
error String
"Foundation.Parser.Internal.Alternative.empty"
    <|> :: forall a. Parser input a -> Parser input a -> Parser input a
(<|>) = Parser input a -> Parser input a -> Parser input a
forall a. Parser input a -> Parser input a -> Parser input a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus
    {-# INLINE (<|>) #-}

runParser_ :: ParserSource input
           => Parser input result
           -> input
           -> Offset (Element input)
           -> NoMore
           -> Failure input        result'
           -> Success input result result'
           -> Result input         result'
runParser_ :: forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ Parser input result
parser input
buf Offset (Element input)
off NoMore
NoMore Failure input result'
err Success input result result'
ok = Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input result
parser input
buf Offset (Element input)
off NoMore
NoMore Failure input result'
err Success input result result'
ok
runParser_ Parser input result
parser input
buf Offset (Element input)
off NoMore
nm     Failure input result'
err Success input result result'
ok
    | input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off = (Chunk input -> Result input result') -> Result input result'
forall input result.
(Chunk input -> Result input result) -> Result input result
ParseMore ((Chunk input -> Result input result') -> Result input result')
-> (Chunk input -> Result input result') -> Result input result'
forall a b. (a -> b) -> a -> b
$ \Chunk input
chunk ->
        if input -> Chunk input -> Bool
forall input. ParserSource input => input -> Chunk input -> Bool
nullChunk input
buf Chunk input
chunk
            then Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input result
parser input
buf Offset (Element input)
off NoMore
NoMore Failure input result'
err Success input result result'
ok
            else Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input result
parser (input -> Chunk input -> input
forall input. ParserSource input => input -> Chunk input -> input
appendChunk input
buf Chunk input
chunk) Offset (Element input)
off NoMore
nm Failure input result'
err Success input result result'
ok
    | Bool
otherwise = Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input result
parser input
buf                    Offset (Element input)
off NoMore
nm Failure input result'
err Success input result result'
ok
{-# INLINE runParser_ #-}

-- | Run a parser on an @initial input.
--
-- If the Parser need more data than available, the @feeder function
-- is automatically called and fed to the More continuation.
parseFeed :: (ParserSource input, Monad m)
          => m (Chunk input)
          -> Parser input a
          -> input
          -> m (Result input a)
parseFeed :: forall input (m :: * -> *) a.
(ParserSource input, Monad m) =>
m (Chunk input) -> Parser input a -> input -> m (Result input a)
parseFeed m (Chunk input)
feeder Parser input a
p input
initial = Result input a -> m (Result input a)
loop (Result input a -> m (Result input a))
-> Result input a -> m (Result input a)
forall a b. (a -> b) -> a -> b
$ Parser input a -> input -> Result input a
forall input a.
ParserSource input =>
Parser input a -> input -> Result input a
parse Parser input a
p input
initial
  where loop :: Result input a -> m (Result input a)
loop (ParseMore Chunk input -> Result input a
k) = m (Chunk input)
feeder m (Chunk input)
-> (Chunk input -> m (Result input a)) -> m (Result input a)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Result input a -> m (Result input a)
loop (Result input a -> m (Result input a))
-> (Chunk input -> Result input a)
-> Chunk input
-> m (Result input a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Chunk input -> Result input a
k)
        loop Result input a
r             = Result input a -> m (Result input a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Result input a
r

-- | Run a Parser on a ByteString and return a 'Result'
parse :: ParserSource input
      => Parser input a -> input -> Result input a
parse :: forall input a.
ParserSource input =>
Parser input a -> input -> Result input a
parse Parser input a
p input
s = Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input a
p input
s Offset (Element input)
0 NoMore
More Failure input a
forall input r.
input
-> Offset (Element input)
-> NoMore
-> ParseError input
-> Result input r
failure Success input a a
forall input r.
ParserSource input =>
input -> Offset (Element input) -> NoMore -> r -> Result input r
success

failure :: input -> Offset (Element input) -> NoMore -> ParseError input -> Result input r
failure :: forall input r.
input
-> Offset (Element input)
-> NoMore
-> ParseError input
-> Result input r
failure input
_ Offset (Element input)
_ NoMore
_ = ParseError input -> Result input r
forall input result. ParseError input -> Result input result
ParseFailed
{-# INLINE failure #-}

success :: ParserSource input => input -> Offset (Element input) -> NoMore -> r -> Result input r
success :: forall input r.
ParserSource input =>
input -> Offset (Element input) -> NoMore -> r -> Result input r
success input
buf Offset (Element input)
off NoMore
_ = Chunk input -> r -> Result input r
forall input result. Chunk input -> result -> Result input result
ParseOk Chunk input
rest
  where
    !rest :: Chunk input
rest = input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off (input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf CountOf (Element input)
-> CountOf (Element input) -> CountOf (Element input)
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` Offset (Element input) -> CountOf (Element input)
forall a. Offset a -> CountOf a
offsetAsSize Offset (Element input)
off)
{-# INLINE success #-}

-- | parse only the given input
--
-- The left-over `Element input` will be ignored, if the parser call for more
-- data it will be continuously fed with `Nothing` (up to 256 iterations).
--
parseOnly :: (ParserSource input, Monoid (Chunk input))
          => Parser input a
          -> input
          -> Either (ParseError input) a
parseOnly :: forall input a.
(ParserSource input, Monoid (Chunk input)) =>
Parser input a -> input -> Either (ParseError input) a
parseOnly Parser input a
p input
i = case Parser input a
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input a result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input a
p input
i Offset (Element input)
0 NoMore
NoMore Failure input a
forall input r.
input
-> Offset (Element input)
-> NoMore
-> ParseError input
-> Result input r
failure Success input a a
forall input r.
ParserSource input =>
input -> Offset (Element input) -> NoMore -> r -> Result input r
success of
    ParseFailed ParseError input
err  -> ParseError input -> Either (ParseError input) a
forall a b. a -> Either a b
Left ParseError input
err
    ParseOk     Chunk input
_ a
r  -> a -> Either (ParseError input) a
forall a b. b -> Either a b
Right a
r
    ParseMore   Chunk input -> Result input a
_    -> ParseError input -> Either (ParseError input) a
forall a b. a -> Either a b
Left ParseError input
forall input. ParseError input
NotEnoughParseOnly

-- ------------------------------------------------------------------------- --
--                              String Parser                                --
-- ------------------------------------------------------------------------- --

instance ParserSource String where
    type Chunk String = String
    nullChunk :: String -> Chunk String -> Bool
nullChunk String
_ = String -> Bool
Chunk String -> Bool
forall c. Collection c => c -> Bool
null
    {-# INLINE nullChunk #-}
    appendChunk :: String -> Chunk String -> String
appendChunk = String -> String -> String
String -> Chunk String -> String
forall a. Monoid a => a -> a -> a
mappend
    {-# INLINE appendChunk #-}
    subChunk :: String
-> Offset (Element String)
-> CountOf (Element String)
-> Chunk String
subChunk String
c Offset (Element String)
off CountOf (Element String)
sz = CountOf (Element (Chunk String)) -> Chunk String -> Chunk String
forall c. Sequential c => CountOf (Element c) -> c -> c
C.take CountOf (Element String)
CountOf (Element (Chunk String))
sz (Chunk String -> Chunk String) -> Chunk String -> Chunk String
forall a b. (a -> b) -> a -> b
$ CountOf (Element String) -> String -> String
forall c. Sequential c => CountOf (Element c) -> c -> c
C.drop (Offset Char -> CountOf Char
forall a. Offset a -> CountOf a
offsetAsSize Offset Char
Offset (Element String)
off) String
c
    {-# INLINE subChunk #-}
    spanChunk :: String
-> Offset (Element String)
-> (Element String -> Bool)
-> (Chunk String, Offset (Element String))
spanChunk String
buf Offset (Element String)
off Element String -> Bool
predicate =
        let c :: String
c      = CountOf (Element String) -> String -> String
forall c. Sequential c => CountOf (Element c) -> c -> c
C.drop (Offset Char -> CountOf Char
forall a. Offset a -> CountOf a
offsetAsSize Offset Char
Offset (Element String)
off) String
buf
            (String
t, String
_) = (Element String -> Bool) -> String -> (String, String)
forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.span Element String -> Bool
predicate String
c
          in (String
Chunk String
t, Offset Char
Offset (Element String)
off Offset Char -> CountOf Char -> Offset Char
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` String -> CountOf (Element String)
forall c. Collection c => c -> CountOf (Element c)
length String
t)
    {-# INLINE spanChunk #-}

instance ParserSource [a] where
    type Chunk [a] = [a]
    nullChunk :: [a] -> Chunk [a] -> Bool
nullChunk [a]
_ = [a] -> Bool
Chunk [a] -> Bool
forall c. Collection c => c -> Bool
null
    {-# INLINE nullChunk #-}
    appendChunk :: [a] -> Chunk [a] -> [a]
appendChunk = [a] -> [a] -> [a]
[a] -> Chunk [a] -> [a]
forall a. Monoid a => a -> a -> a
mappend
    {-# INLINE appendChunk #-}
    subChunk :: [a] -> Offset (Element [a]) -> CountOf (Element [a]) -> Chunk [a]
subChunk [a]
c Offset (Element [a])
off CountOf (Element [a])
sz = CountOf (Element (Chunk [a])) -> Chunk [a] -> Chunk [a]
forall c. Sequential c => CountOf (Element c) -> c -> c
C.take CountOf (Element [a])
CountOf (Element (Chunk [a]))
sz (Chunk [a] -> Chunk [a]) -> Chunk [a] -> Chunk [a]
forall a b. (a -> b) -> a -> b
$ CountOf (Element [a]) -> [a] -> [a]
forall c. Sequential c => CountOf (Element c) -> c -> c
C.drop (Offset a -> CountOf a
forall a. Offset a -> CountOf a
offsetAsSize Offset a
Offset (Element [a])
off) [a]
c
    {-# INLINE subChunk #-}
    spanChunk :: [a]
-> Offset (Element [a])
-> (Element [a] -> Bool)
-> (Chunk [a], Offset (Element [a]))
spanChunk [a]
buf Offset (Element [a])
off Element [a] -> Bool
predicate =
        let c :: [a]
c      = CountOf (Element [a]) -> [a] -> [a]
forall c. Sequential c => CountOf (Element c) -> c -> c
C.drop (Offset a -> CountOf a
forall a. Offset a -> CountOf a
offsetAsSize Offset a
Offset (Element [a])
off) [a]
buf
            ([a]
t, [a]
_) = (Element [a] -> Bool) -> [a] -> ([a], [a])
forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
C.span Element [a] -> Bool
predicate [a]
c
          in ([a]
Chunk [a]
t, Offset a
Offset (Element [a])
off Offset a -> CountOf a -> Offset a
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` [a] -> CountOf (Element [a])
forall c. Collection c => c -> CountOf (Element c)
length [a]
t)
    {-# INLINE spanChunk #-}

-- ------------------------------------------------------------------------- --
--                          Helpers                                          --
-- ------------------------------------------------------------------------- --

-- | helper function to report error when writing parsers
--
-- This way we can provide more detailed error when building custom
-- parsers and still avoid to use the naughty _fail_.
--
-- @
-- myParser :: Parser input Int
-- myParser = reportError $ Satisfy (Just "this function is not implemented...")
-- @
--
reportError :: ParseError input -> Parser input a
reportError :: forall input a. ParseError input -> Parser input a
reportError ParseError input
pe = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input a result'
 -> Result input result')
-> Parser input a
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input a result'
  -> Result input result')
 -> Parser input a)
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input a result'
    -> Result input result')
-> Parser input a
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input a result'
_ -> Failure input result'
err input
buf Offset (Element input)
off NoMore
nm ParseError input
pe

-- | Get the next `Element input` from the parser
anyElement :: ParserSource input => Parser input (Element input)
anyElement :: forall input. ParserSource input => Parser input (Element input)
anyElement = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Element input) result'
 -> Result input result')
-> Parser input (Element input)
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Element input) result'
  -> Result input result')
 -> Parser input (Element input))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Element input) result'
    -> Result input result')
-> Parser input (Element input)
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Element input) result'
ok ->
    case input
buf input -> Offset (Element input) -> Maybe (Element input)
forall c.
IndexedCollection c =>
c -> Offset (Element c) -> Maybe (Element c)
! Offset (Element input)
off of
        Maybe (Element input)
Nothing -> Failure input result'
err input
buf Offset (Element input)
off        NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
1
        Just Element input
x  -> Success input (Element input) result'
ok  input
buf (Offset (Element input) -> Offset (Element input)
forall a. Enum a => a -> a
succ Offset (Element input)
off) NoMore
nm Element input
x
{-# INLINE anyElement #-}

-- | peek the first element from the input source without consuming it
--
-- Returns 'Nothing' if there is no more input to parse.
--
peek :: ParserSource input => Parser input (Maybe (Element input))
peek :: forall input.
ParserSource input =>
Parser input (Maybe (Element input))
peek = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Maybe (Element input)) result'
 -> Result input result')
-> Parser input (Maybe (Element input))
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Maybe (Element input)) result'
  -> Result input result')
 -> Parser input (Maybe (Element input)))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Maybe (Element input)) result'
    -> Result input result')
-> Parser input (Maybe (Element input))
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Maybe (Element input)) result'
ok ->
    case input
buf input -> Offset (Element input) -> Maybe (Element input)
forall c.
IndexedCollection c =>
c -> Offset (Element c) -> Maybe (Element c)
! Offset (Element input)
off of
        Maybe (Element input)
Nothing -> Parser input (Maybe (Element input))
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input (Maybe (Element input)) result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ Parser input (Maybe (Element input))
peekOnly input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Maybe (Element input)) result'
ok
        Just Element input
x  -> Success input (Maybe (Element input)) result'
ok input
buf Offset (Element input)
off NoMore
nm (Element input -> Maybe (Element input)
forall a. a -> Maybe a
Just Element input
x)
  where
    peekOnly :: Parser input (Maybe (Element input))
peekOnly = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Maybe (Element input)) result'
 -> Result input result')
-> Parser input (Maybe (Element input))
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Maybe (Element input)) result'
  -> Result input result')
 -> Parser input (Maybe (Element input)))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Maybe (Element input)) result'
    -> Result input result')
-> Parser input (Maybe (Element input))
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
_ Success input (Maybe (Element input)) result'
ok ->
        Success input (Maybe (Element input)) result'
ok input
buf Offset (Element input)
off NoMore
nm (input
buf input -> Offset (Element input) -> Maybe (Element input)
forall c.
IndexedCollection c =>
c -> Offset (Element c) -> Maybe (Element c)
! Offset (Element input)
off)

element :: ( ParserSource input
           , Eq (Element input)
           , Element input ~ Element (Chunk input)
           )
        => Element input
        -> Parser input ()
element :: forall input.
(ParserSource input, Eq (Element input),
 Element input ~ Element (Chunk input)) =>
Element input -> Parser input ()
element Element input
expectedElement = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
    case input
buf input -> Offset (Element input) -> Maybe (Element input)
forall c.
IndexedCollection c =>
c -> Offset (Element c) -> Maybe (Element c)
! Offset (Element input)
off of
        Maybe (Element input)
Nothing -> Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
CountOf (Element (Chunk input))
1
        Just Element input
x | Element input
Element (Chunk input)
expectedElement Element (Chunk input) -> Element (Chunk input) -> Bool
forall a. Eq a => a -> a -> Bool
== Element input
Element (Chunk input)
x -> Success input () result'
ok  input
buf (Offset (Element (Chunk input)) -> Offset (Element (Chunk input))
forall a. Enum a => a -> a
succ Offset (Element input)
Offset (Element (Chunk input))
off) NoMore
nm ()
               | Bool
otherwise            -> Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ Element input -> Element input -> ParseError input
forall input. Element input -> Element input -> ParseError input
ExpectedElement Element input
expectedElement Element input
x
{-# INLINE element #-}

elements :: ( ParserSource input, Sequential (Chunk input)
            , Element (Chunk input) ~ Element input
            , Eq (Chunk input)
            )
         => Chunk input -> Parser input ()
elements :: forall input.
(ParserSource input, Sequential (Chunk input),
 Element (Chunk input) ~ Element input, Eq (Chunk input)) =>
Chunk input -> Parser input ()
elements = Chunk input -> Parser input ()
forall input.
(ParserSource input, Sequential (Chunk input),
 Element (Chunk input) ~ Element input, Eq (Chunk input)) =>
Chunk input -> Parser input ()
consumeEq
  where
    consumeEq :: ( ParserSource input
                 , Sequential (Chunk input)
                 , Element (Chunk input) ~ Element input
                 , Eq (Chunk input)
                 )
              => Chunk input -> Parser input ()
    consumeEq :: forall input.
(ParserSource input, Sequential (Chunk input),
 Element (Chunk input) ~ Element input, Eq (Chunk input)) =>
Chunk input -> Parser input ()
consumeEq Chunk input
expected = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
      if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off
        then
          Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
CountOf (Element (Chunk input))
lenE
        else
          let !lenI :: Difference (Offset (Element input))
lenI = CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset (input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf) Offset (Element input)
-> Offset (Element input) -> Difference (Offset (Element input))
forall a. Subtractive a => a -> a -> Difference a
- Offset (Element input)
off
           in if Difference (Offset (Element input))
CountOf (Element input)
lenI CountOf (Element input) -> CountOf (Element input) -> Bool
forall a. Ord a => a -> a -> Bool
>= CountOf (Element input)
CountOf (Element (Chunk input))
lenE
             then
              let a :: Chunk input
a = input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off CountOf (Element input)
CountOf (Element (Chunk input))
lenE
               in if Chunk input
a Chunk input -> Chunk input -> Bool
forall a. Eq a => a -> a -> Bool
== Chunk input
expected
                    then Success input () result'
ok input
buf (Offset (Element input)
off Offset (Element input)
-> Offset (Element input) -> Offset (Element input)
forall a. Additive a => a -> a -> a
+ CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset CountOf (Element input)
CountOf (Element (Chunk input))
lenE) NoMore
nm ()
                    else Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ Chunk input -> Chunk input -> ParseError input
forall input. Chunk input -> Chunk input -> ParseError input
Expected Chunk input
expected Chunk input
a
             else
              let a :: Chunk input
a = input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off Difference (Offset (Element input))
CountOf (Element input)
lenI
                  (Chunk input
e', Chunk input
r) = CountOf (Element (Chunk input))
-> Chunk input -> (Chunk input, Chunk input)
forall c. Sequential c => CountOf (Element c) -> c -> (c, c)
splitAt Difference (Offset (Element input))
CountOf (Element (Chunk input))
lenI Chunk input
expected
               in if Chunk input
a Chunk input -> Chunk input -> Bool
forall a. Eq a => a -> a -> Bool
== Chunk input
e'
                    then Parser input ()
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input () result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ (Chunk input -> Parser input ()
forall input.
(ParserSource input, Sequential (Chunk input),
 Element (Chunk input) ~ Element input, Eq (Chunk input)) =>
Chunk input -> Parser input ()
consumeEq Chunk input
r) input
buf (Offset (Element input)
off Offset (Element input)
-> Offset (Element input) -> Offset (Element input)
forall a. Additive a => a -> a -> a
+ CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset Difference (Offset (Element input))
CountOf (Element input)
lenI) NoMore
nm Failure input result'
err Success input () result'
ok
                    else Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ Chunk input -> Chunk input -> ParseError input
forall input. Chunk input -> Chunk input -> ParseError input
Expected Chunk input
e' Chunk input
a
      where
        !lenE :: CountOf (Element (Chunk input))
lenE = Chunk input -> CountOf (Element (Chunk input))
forall c. Collection c => c -> CountOf (Element c)
length Chunk input
expected
    {-# NOINLINE consumeEq #-}
{-# INLINE elements #-}

-- | take one element if satisfy the given predicate
satisfy :: ParserSource input => Maybe String -> (Element input -> Bool) -> Parser input (Element input)
satisfy :: forall input.
ParserSource input =>
Maybe String
-> (Element input -> Bool) -> Parser input (Element input)
satisfy Maybe String
desc Element input -> Bool
predicate = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Element input) result'
 -> Result input result')
-> Parser input (Element input)
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Element input) result'
  -> Result input result')
 -> Parser input (Element input))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Element input) result'
    -> Result input result')
-> Parser input (Element input)
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Element input) result'
ok ->
    case input
buf input -> Offset (Element input) -> Maybe (Element input)
forall c.
IndexedCollection c =>
c -> Offset (Element c) -> Maybe (Element c)
! Offset (Element input)
off of
        Maybe (Element input)
Nothing -> Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
1
        Just Element input
x | Element input -> Bool
predicate Element input
x -> Success input (Element input) result'
ok  input
buf (Offset (Element input) -> Offset (Element input)
forall a. Enum a => a -> a
succ Offset (Element input)
off) NoMore
nm Element input
x
               | Bool
otherwise   -> Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ Maybe String -> ParseError input
forall input. Maybe String -> ParseError input
Satisfy Maybe String
desc
{-# INLINE satisfy #-}

-- | take one element if satisfy the given predicate
satisfy_ :: ParserSource input => (Element input -> Bool) -> Parser input (Element input)
satisfy_ :: forall input.
ParserSource input =>
(Element input -> Bool) -> Parser input (Element input)
satisfy_ = Maybe String
-> (Element input -> Bool) -> Parser input (Element input)
forall input.
ParserSource input =>
Maybe String
-> (Element input -> Bool) -> Parser input (Element input)
satisfy Maybe String
forall a. Maybe a
Nothing
{-# INLINE satisfy_ #-}

take :: ( ParserSource input
        , Sequential (Chunk input)
        , Element input ~ Element (Chunk input)
        )
     => CountOf (Element (Chunk input))
     -> Parser input (Chunk input)
take :: forall input.
(ParserSource input, Sequential (Chunk input),
 Element input ~ Element (Chunk input)) =>
CountOf (Element (Chunk input)) -> Parser input (Chunk input)
take CountOf (Element (Chunk input))
n = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Chunk input) result'
 -> Result input result')
-> Parser input (Chunk input)
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Chunk input) result'
  -> Result input result')
 -> Parser input (Chunk input))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Chunk input) result'
    -> Result input result')
-> Parser input (Chunk input)
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Chunk input) result'
ok ->
    let lenI :: Difference (Offset (Element (Chunk input)))
lenI = CountOf (Element (Chunk input)) -> Offset (Element (Chunk input))
forall a. CountOf a -> Offset a
sizeAsOffset (input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf) Offset (Element (Chunk input))
-> Offset (Element (Chunk input))
-> Difference (Offset (Element (Chunk input)))
forall a. Subtractive a => a -> a -> Difference a
- Offset (Element input)
Offset (Element (Chunk input))
off
     in if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off Bool -> Bool -> Bool
&& CountOf (Element (Chunk input))
n CountOf (Element (Chunk input))
-> CountOf (Element (Chunk input)) -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf (Element (Chunk input))
0
       then Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
CountOf (Element (Chunk input))
n
       else case CountOf (Element (Chunk input))
n CountOf (Element (Chunk input))
-> CountOf (Element (Chunk input))
-> Difference (CountOf (Element (Chunk input)))
forall a. Subtractive a => a -> a -> Difference a
- Difference (Offset (Element (Chunk input)))
CountOf (Element (Chunk input))
lenI of
              Just CountOf (Element (Chunk input))
s | CountOf (Element (Chunk input))
s CountOf (Element (Chunk input))
-> CountOf (Element (Chunk input)) -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf (Element (Chunk input))
0 -> let h :: Chunk input
h = input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off Difference (Offset (Element (Chunk input)))
CountOf (Element input)
lenI
                                 in Parser input (Chunk input)
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input (Chunk input) result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ (CountOf (Element (Chunk input)) -> Parser input (Chunk input)
forall input.
(ParserSource input, Sequential (Chunk input),
 Element input ~ Element (Chunk input)) =>
CountOf (Element (Chunk input)) -> Parser input (Chunk input)
take CountOf (Element (Chunk input))
s) input
buf (CountOf (Element (Chunk input)) -> Offset (Element (Chunk input))
forall a. CountOf a -> Offset a
sizeAsOffset Difference (Offset (Element (Chunk input)))
CountOf (Element (Chunk input))
lenI) NoMore
nm Failure input result'
err (Success input (Chunk input) result' -> Result input result')
-> Success input (Chunk input) result' -> Result input result'
forall a b. (a -> b) -> a -> b
$
                                      \input
buf' Offset (Element input)
off' NoMore
nm' Chunk input
t -> Success input (Chunk input) result'
ok input
buf' Offset (Element input)
off' NoMore
nm' (Chunk input
h Chunk input -> Chunk input -> Chunk input
forall a. Semigroup a => a -> a -> a
<> Chunk input
t)
              Difference (CountOf (Element (Chunk input)))
_              -> Success input (Chunk input) result'
ok input
buf (Offset (Element input)
Offset (Element (Chunk input))
off Offset (Element (Chunk input))
-> Offset (Element (Chunk input)) -> Offset (Element (Chunk input))
forall a. Additive a => a -> a -> a
+ CountOf (Element (Chunk input)) -> Offset (Element (Chunk input))
forall a. CountOf a -> Offset a
sizeAsOffset CountOf (Element (Chunk input))
n) NoMore
nm (input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off CountOf (Element input)
CountOf (Element (Chunk input))
n)

takeWhile :: ( ParserSource input, Sequential (Chunk input)
             )
          => (Element input -> Bool)
          -> Parser input (Chunk input)
takeWhile :: forall input.
(ParserSource input, Sequential (Chunk input)) =>
(Element input -> Bool) -> Parser input (Chunk input)
takeWhile Element input -> Bool
predicate = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Chunk input) result'
 -> Result input result')
-> Parser input (Chunk input)
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Chunk input) result'
  -> Result input result')
 -> Parser input (Chunk input))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Chunk input) result'
    -> Result input result')
-> Parser input (Chunk input)
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input (Chunk input) result'
ok ->
    if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off
      then Success input (Chunk input) result'
ok input
buf Offset (Element input)
off NoMore
nm Chunk input
forall a. Monoid a => a
mempty
      else let (Chunk input
b1, Offset (Element input)
off') = input
-> Offset (Element input)
-> (Element input -> Bool)
-> (Chunk input, Offset (Element input))
forall input.
ParserSource input =>
input
-> Offset (Element input)
-> (Element input -> Bool)
-> (Chunk input, Offset (Element input))
spanChunk input
buf Offset (Element input)
off Element input -> Bool
predicate
            in if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off'
                  then Parser input (Chunk input)
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input (Chunk input) result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ ((Element input -> Bool) -> Parser input (Chunk input)
forall input.
(ParserSource input, Sequential (Chunk input)) =>
(Element input -> Bool) -> Parser input (Chunk input)
takeWhile Element input -> Bool
predicate) input
buf Offset (Element input)
off' NoMore
nm Failure input result'
err
                          (Success input (Chunk input) result' -> Result input result')
-> Success input (Chunk input) result' -> Result input result'
forall a b. (a -> b) -> a -> b
$ \input
buf' Offset (Element input)
off'' NoMore
nm' Chunk input
b1T -> Success input (Chunk input) result'
ok input
buf' Offset (Element input)
off'' NoMore
nm' (Chunk input
b1 Chunk input -> Chunk input -> Chunk input
forall a. Semigroup a => a -> a -> a
<> Chunk input
b1T)
                  else Success input (Chunk input) result'
ok input
buf Offset (Element input)
off' NoMore
nm Chunk input
b1

-- | Take the remaining elements from the current position in the stream
takeAll :: (ParserSource input, Sequential (Chunk input)) => Parser input (Chunk input)
takeAll :: forall input.
(ParserSource input, Sequential (Chunk input)) =>
Parser input (Chunk input)
takeAll = Parser input ()
forall input.
(ParserSource input, Sequential (Chunk input)) =>
Parser input ()
getAll Parser input ()
-> Parser input (Chunk input) -> Parser input (Chunk input)
forall a b. Parser input a -> Parser input b -> Parser input b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser input (Chunk input)
forall input. ParserSource input => Parser input (Chunk input)
returnBuffer
  where
    returnBuffer :: ParserSource input => Parser input (Chunk input)
    returnBuffer :: forall input. ParserSource input => Parser input (Chunk input)
returnBuffer = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input (Chunk input) result'
 -> Result input result')
-> Parser input (Chunk input)
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input (Chunk input) result'
  -> Result input result')
 -> Parser input (Chunk input))
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input (Chunk input) result'
    -> Result input result')
-> Parser input (Chunk input)
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
_ Success input (Chunk input) result'
ok ->
        let !lenI :: CountOf (Element input)
lenI = input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf
            !off' :: Offset (Element input)
off' = CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset CountOf (Element input)
lenI
            !sz :: Difference (Offset (Element input))
sz   = Offset (Element input)
off' Offset (Element input)
-> Offset (Element input) -> Difference (Offset (Element input))
forall a. Subtractive a => a -> a -> Difference a
- Offset (Element input)
off
         in Success input (Chunk input) result'
ok input
buf Offset (Element input)
off' NoMore
nm (input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
forall input.
ParserSource input =>
input
-> Offset (Element input) -> CountOf (Element input) -> Chunk input
subChunk input
buf Offset (Element input)
off Difference (Offset (Element input))
CountOf (Element input)
sz)
    {-# INLINE returnBuffer #-}

    getAll :: (ParserSource input, Sequential (Chunk input)) => Parser input ()
    getAll :: forall input.
(ParserSource input, Sequential (Chunk input)) =>
Parser input ()
getAll = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
      case NoMore
nm of
        NoMore
NoMore -> Success input () result'
ok input
buf Offset (Element input)
off NoMore
nm ()
        NoMore
More   -> (Chunk input -> Result input result') -> Result input result'
forall input result.
(Chunk input -> Result input result) -> Result input result
ParseMore ((Chunk input -> Result input result') -> Result input result')
-> (Chunk input -> Result input result') -> Result input result'
forall a b. (a -> b) -> a -> b
$ \Chunk input
nextChunk ->
          if input -> Chunk input -> Bool
forall input. ParserSource input => input -> Chunk input -> Bool
nullChunk input
buf Chunk input
nextChunk
            then Success input () result'
ok input
buf Offset (Element input)
off NoMore
NoMore ()
            else Parser input ()
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input () result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input ()
forall input.
(ParserSource input, Sequential (Chunk input)) =>
Parser input ()
getAll (input -> Chunk input -> input
forall input. ParserSource input => input -> Chunk input -> input
appendChunk input
buf Chunk input
nextChunk) Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok
    {-# NOINLINE getAll #-}
{-# INLINE takeAll #-}

skip :: ParserSource input => CountOf (Element input) -> Parser input ()
skip :: forall input.
ParserSource input =>
CountOf (Element input) -> Parser input ()
skip CountOf (Element input)
n = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
    let lenI :: Difference (Offset (Element input))
lenI = CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset (input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf) Offset (Element input)
-> Offset (Element input) -> Difference (Offset (Element input))
forall a. Subtractive a => a -> a -> Difference a
- Offset (Element input)
off
     in if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off Bool -> Bool -> Bool
&& CountOf (Element input)
n CountOf (Element input) -> CountOf (Element input) -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf (Element input)
0
       then Failure input result'
err input
buf Offset (Element input)
off NoMore
nm (ParseError input -> Result input result')
-> ParseError input -> Result input result'
forall a b. (a -> b) -> a -> b
$ CountOf (Element input) -> ParseError input
forall input. CountOf (Element input) -> ParseError input
NotEnough CountOf (Element input)
n
       else case CountOf (Element input)
n CountOf (Element input)
-> CountOf (Element input) -> Difference (CountOf (Element input))
forall a. Subtractive a => a -> a -> Difference a
- Difference (Offset (Element input))
CountOf (Element input)
lenI of
              Just CountOf (Element input)
s | CountOf (Element input)
s CountOf (Element input) -> CountOf (Element input) -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf (Element input)
0 -> Parser input ()
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input () result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ (CountOf (Element input) -> Parser input ()
forall input.
ParserSource input =>
CountOf (Element input) -> Parser input ()
skip CountOf (Element input)
s) input
buf (CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset Difference (Offset (Element input))
CountOf (Element input)
lenI) NoMore
nm Failure input result'
err Success input () result'
ok
              Difference (CountOf (Element input))
_              -> Success input () result'
ok input
buf (Offset (Element input)
off Offset (Element input)
-> Offset (Element input) -> Offset (Element input)
forall a. Additive a => a -> a -> a
+ CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset CountOf (Element input)
n) NoMore
nm ()

skipWhile :: ( ParserSource input, Sequential (Chunk input)
             )
          => (Element input -> Bool)
          -> Parser input ()
skipWhile :: forall input.
(ParserSource input, Sequential (Chunk input)) =>
(Element input -> Bool) -> Parser input ()
skipWhile Element input -> Bool
predicate = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
    if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off
      then Success input () result'
ok input
buf Offset (Element input)
off NoMore
nm ()
      else let (Chunk input
_, Offset (Element input)
off') = input
-> Offset (Element input)
-> (Element input -> Bool)
-> (Chunk input, Offset (Element input))
forall input.
ParserSource input =>
input
-> Offset (Element input)
-> (Element input -> Bool)
-> (Chunk input, Offset (Element input))
spanChunk input
buf Offset (Element input)
off Element input -> Bool
predicate
            in if input -> Offset (Element input) -> Bool
forall input.
ParserSource input =>
input -> Offset (Element input) -> Bool
endOfParserSource input
buf Offset (Element input)
off'
                  then Parser input ()
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input () result'
-> Result input result'
forall input result result'.
ParserSource input =>
Parser input result
-> input
-> Offset (Element input)
-> NoMore
-> Failure input result'
-> Success input result result'
-> Result input result'
runParser_ ((Element input -> Bool) -> Parser input ()
forall input.
(ParserSource input, Sequential (Chunk input)) =>
(Element input -> Bool) -> Parser input ()
skipWhile Element input -> Bool
predicate) input
buf Offset (Element input)
off' NoMore
nm Failure input result'
err Success input () result'
ok
                  else Success input () result'
ok input
buf Offset (Element input)
off' NoMore
nm ()

-- | consume every chunk of the stream
--
skipAll :: (ParserSource input, Collection (Chunk input)) => Parser input ()
skipAll :: forall input.
(ParserSource input, Collection (Chunk input)) =>
Parser input ()
skipAll = Parser input ()
forall input.
(ParserSource input, Collection (Chunk input)) =>
Parser input ()
flushAll
  where
    flushAll :: (ParserSource input, Collection (Chunk input)) => Parser input ()
    flushAll :: forall input.
(ParserSource input, Collection (Chunk input)) =>
Parser input ()
flushAll = (forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input () result'
 -> Result input result')
-> Parser input ()
forall input result.
(forall result'.
 input
 -> Offset (Element input)
 -> NoMore
 -> Failure input result'
 -> Success input result result'
 -> Result input result')
-> Parser input result
Parser ((forall result'.
  input
  -> Offset (Element input)
  -> NoMore
  -> Failure input result'
  -> Success input () result'
  -> Result input result')
 -> Parser input ())
-> (forall result'.
    input
    -> Offset (Element input)
    -> NoMore
    -> Failure input result'
    -> Success input () result'
    -> Result input result')
-> Parser input ()
forall a b. (a -> b) -> a -> b
$ \input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok ->
        let !off' :: Offset (Element input)
off' = CountOf (Element input) -> Offset (Element input)
forall a. CountOf a -> Offset a
sizeAsOffset (CountOf (Element input) -> Offset (Element input))
-> CountOf (Element input) -> Offset (Element input)
forall a b. (a -> b) -> a -> b
$ input -> CountOf (Element input)
forall c. Collection c => c -> CountOf (Element c)
length input
buf in
        case NoMore
nm of
            NoMore
NoMore -> Success input () result'
ok input
buf Offset (Element input)
off' NoMore
NoMore ()
            NoMore
More   -> (Chunk input -> Result input result') -> Result input result'
forall input result.
(Chunk input -> Result input result) -> Result input result
ParseMore ((Chunk input -> Result input result') -> Result input result')
-> (Chunk input -> Result input result') -> Result input result'
forall a b. (a -> b) -> a -> b
$ \Chunk input
nextChunk ->
              if Chunk input -> Bool
forall c. Collection c => c -> Bool
null Chunk input
nextChunk
                then Success input () result'
ok input
buf Offset (Element input)
off' NoMore
NoMore ()
                else Parser input ()
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input () result'
   -> Result input result'
forall input result.
Parser input result
-> forall result'.
   input
   -> Offset (Element input)
   -> NoMore
   -> Failure input result'
   -> Success input result result'
   -> Result input result'
runParser Parser input ()
forall input.
(ParserSource input, Collection (Chunk input)) =>
Parser input ()
flushAll input
buf Offset (Element input)
off NoMore
nm Failure input result'
err Success input () result'
ok
    {-# NOINLINE flushAll #-}
{-# INLINE skipAll #-}

string :: String -> Parser String ()
string :: String -> Parser String ()
string = String -> Parser String ()
Chunk String -> Parser String ()
forall input.
(ParserSource input, Sequential (Chunk input),
 Element (Chunk input) ~ Element input, Eq (Chunk input)) =>
Chunk input -> Parser input ()
elements
{-# INLINE string #-}

data Condition = Between !And | Exactly !Word
  deriving (Int -> Condition -> ShowS
[Condition] -> ShowS
Condition -> String
(Int -> Condition -> ShowS)
-> (Condition -> String)
-> ([Condition] -> ShowS)
-> Show Condition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Condition -> ShowS
showsPrec :: Int -> Condition -> ShowS
$cshow :: Condition -> String
show :: Condition -> String
$cshowList :: [Condition] -> ShowS
showList :: [Condition] -> ShowS
Show, Condition -> Condition -> Bool
(Condition -> Condition -> Bool)
-> (Condition -> Condition -> Bool) -> Eq Condition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Condition -> Condition -> Bool
== :: Condition -> Condition -> Bool
$c/= :: Condition -> Condition -> Bool
/= :: Condition -> Condition -> Bool
Eq, Typeable)
data And = And !Word !Word
  deriving (And -> And -> Bool
(And -> And -> Bool) -> (And -> And -> Bool) -> Eq And
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: And -> And -> Bool
== :: And -> And -> Bool
$c/= :: And -> And -> Bool
/= :: And -> And -> Bool
Eq, Typeable)
instance Show And where
    show :: And -> String
show (And Word
a Word
b) = Word -> String
forall a. Show a => a -> String
show Word
a String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" and " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word -> String
forall a. Show a => a -> String
show Word
b

-- | repeat the given parser a given amount of time
--
-- Unlike @some@ or @many@, this operation will bring more precision on how
-- many times you wish a parser to be sequenced.
--
-- ## Repeat @Exactly@ a number of time
--
-- > repeat (Exactly 6) (takeWhile ((/=) ',') <* element ',')
--
-- ## Repeat @Between@ lower `@And@` upper times
--
-- > repeat (Between $ 1 `And` 10) (takeWhile ((/=) ',') <* element ',')
--
repeat :: ParserSource input
       => Condition -> Parser input a -> Parser input [a]
repeat :: forall input a.
ParserSource input =>
Condition -> Parser input a -> Parser input [a]
repeat (Exactly Word
n) = Word -> Parser input a -> Parser input [a]
forall input a.
ParserSource input =>
Word -> Parser input a -> Parser input [a]
repeatE Word
n
repeat (Between And
a) = And -> Parser input a -> Parser input [a]
forall input a.
ParserSource input =>
And -> Parser input a -> Parser input [a]
repeatA And
a

repeatE :: (ParserSource input)
        => Word -> Parser input a -> Parser input [a]
repeatE :: forall input a.
ParserSource input =>
Word -> Parser input a -> Parser input [a]
repeatE Word
0 Parser input a
_ = [a] -> Parser input [a]
forall a. a -> Parser input a
forall (m :: * -> *) a. Monad m => a -> m a
return []
repeatE Word
n Parser input a
p = (:) (a -> [a] -> [a]) -> Parser input a -> Parser input ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser input a
p Parser input ([a] -> [a]) -> Parser input [a] -> Parser input [a]
forall a b.
Parser input (a -> b) -> Parser input a -> Parser input b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word -> Parser input a -> Parser input [a]
forall input a.
ParserSource input =>
Word -> Parser input a -> Parser input [a]
repeatE (Word
nWord -> Word -> Difference Word
forall a. Subtractive a => a -> a -> Difference a
-Word
1) Parser input a
p

repeatA :: (ParserSource input)
        => And -> Parser input a -> Parser input [a]
repeatA :: forall input a.
ParserSource input =>
And -> Parser input a -> Parser input [a]
repeatA (And Word
0 Word
0) Parser input a
_ = [a] -> Parser input [a]
forall a. a -> Parser input a
forall (m :: * -> *) a. Monad m => a -> m a
return []
repeatA (And Word
0 Word
n) Parser input a
p = ((:) (a -> [a] -> [a]) -> Parser input a -> Parser input ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser input a
p Parser input ([a] -> [a]) -> Parser input [a] -> Parser input [a]
forall a b.
Parser input (a -> b) -> Parser input a -> Parser input b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> And -> Parser input a -> Parser input [a]
forall input a.
ParserSource input =>
And -> Parser input a -> Parser input [a]
repeatA (Word -> Word -> And
And Word
0     (Word
nWord -> Word -> Difference Word
forall a. Subtractive a => a -> a -> Difference a
-Word
1)) Parser input a
p) Parser input [a] -> Parser input [a] -> Parser input [a]
forall a. Parser input a -> Parser input a -> Parser input a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parser input [a]
forall a. a -> Parser input a
forall (m :: * -> *) a. Monad m => a -> m a
return []
repeatA (And Word
l Word
u) Parser input a
p =  (:) (a -> [a] -> [a]) -> Parser input a -> Parser input ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser input a
p Parser input ([a] -> [a]) -> Parser input [a] -> Parser input [a]
forall a b.
Parser input (a -> b) -> Parser input a -> Parser input b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> And -> Parser input a -> Parser input [a]
forall input a.
ParserSource input =>
And -> Parser input a -> Parser input [a]
repeatA (Word -> Word -> And
And (Word
lWord -> Word -> Difference Word
forall a. Subtractive a => a -> a -> Difference a
-Word
1) (Word
uWord -> Word -> Difference Word
forall a. Subtractive a => a -> a -> Difference a
-Word
1)) Parser input a
p