{-|
Module      : Z.Data.Parser.Base
Description : Efficient deserialization/parse.
Copyright   : (c) Dong Han, 2017-2019
License     : BSD
Maintainer  : winterland1989@gmail.com
Stability   : experimental
Portability : non-portable

This module provide internal data types for a simple resumable 'Parser', which is suitable for binary protocol and simple textual protocol parsing. 'Parser' extensively works on on 'V.Bytes', which is same to 'T.Text' representation.

-}

module Z.Data.Parser.Base
  ( -- * Parser types
    Result(..)
  , ParseError
  , ParseStep
  , Parser(..)
  , (<?>)
    -- * Running a parser
  , parse, parse', parseChunk, parseChunkList, ParseChunks, parseChunks, finishParsing
  , runAndKeepTrack, match
    -- * Basic parsers
  , ensureN, endOfInput, currentChunk, atEnd
    -- * Primitive decoders
  , decodePrim, BE(..), LE(..)
  , decodePrimLE, decodePrimBE
    -- * More parsers
  , scan, scanChunks, peekMaybe, peek, satisfy, satisfyWith
  , anyWord8, word8, char8, anyChar8, anyCharUTF8, charUTF8, char7, anyChar7
  , skipWord8, endOfLine, skip, skipWhile, skipSpaces
  , take, takeN, takeTill, takeWhile, takeWhile1, takeRemaining, takeUTF8,  bytes, bytesCI
  , text
    -- * Error reporting
  , fail', failWithInput, unsafeLiftIO
    -- * Specialized primitive parser
  , decodeWord  , decodeWord64, decodeWord32, decodeWord16, decodeWord8
  , decodeInt   , decodeInt64 , decodeInt32 , decodeInt16 , decodeInt8 , decodeDouble, decodeFloat
  , decodeWordLE  , decodeWord64LE , decodeWord32LE , decodeWord16LE
  , decodeIntLE   , decodeInt64LE , decodeInt32LE , decodeInt16LE , decodeDoubleLE , decodeFloatLE
  , decodeWordBE  , decodeWord64BE , decodeWord32BE , decodeWord16BE
  , decodeIntBE   , decodeInt64BE , decodeInt32BE , decodeInt16BE , decodeDoubleBE , decodeFloatBE
  ) where

import           Control.Applicative
import           Control.Exception                  (assert)
import           Control.Monad
import           Control.Monad.Primitive
import qualified Control.Monad.Fail                 as Fail
import qualified Data.CaseInsensitive               as CI
import qualified Data.Primitive.PrimArray           as A
import           Data.Int
import           Data.Word
import           Data.Bits                          ((.&.))
import           GHC.IO
import           GHC.Exts                           (State#, runRW#, unsafeCoerce#)
import           Prelude                            hiding (take, takeWhile, decodeFloat)
import           Z.Data.Array.Unaligned
import           Z.Data.ASCII
import qualified Z.Data.Text                        as T
import qualified Z.Data.Text.Base                   as T
import qualified Z.Data.Text.UTF8Codec              as T
import qualified Z.Data.Vector.Base                 as V
import qualified Z.Data.Vector.Extra                as V

-- | Simple parsing result, that represent respectively:
--
-- * Success: the remaining unparsed data and the parsed value
--
-- * Failure: the remaining unparsed data and the error message
--
-- * Partial: that need for more input data, supply empty bytes to indicate 'endOfInput'
--
data Result e r
    = Success r !V.Bytes
    | Failure e !V.Bytes
    | Partial (ParseStep e r)

-- | A parse step consumes 'V.Bytes' and produce 'Result'.
type ParseStep e r = V.Bytes -> Result e r

-- | Type alias for error message
type ParseError = [T.Text]

instance Functor (Result e) where
    fmap :: forall a b. (a -> b) -> Result e a -> Result e b
fmap a -> b
f (Success a
a Bytes
s)   = forall e r. r -> Bytes -> Result e r
Success (a -> b
f a
a) Bytes
s
    fmap a -> b
f (Partial ParseStep e a
k)     = forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseStep e a
k)
    fmap a -> b
_ (Failure e
e Bytes
v)   = forall e r. e -> Bytes -> Result e r
Failure e
e Bytes
v

instance (Show e, Show a) => Show (Result e a) where
    show :: Result e a -> String
show (Success a
a Bytes
_)    = String
"Success " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
a
    show (Partial ParseStep e a
_)      = String
"Partial _"
    show (Failure e
errs Bytes
_) = String
"Failure: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show e
errs

-- | Simple CPSed parser
--
-- A parser takes a failure continuation, and a success one, while the success continuation is
-- usually composed by 'Monad' instance, the failure one is more like a reader part, which can
-- be modified via '<?>'. If you build parsers from ground, a pattern like this can be used:
--
--  @
--    xxParser = do
--      ensureN errMsg ...            -- make sure we have some bytes
--      Parser $ \ kf k s inp ->      -- fail continuation, success continuation, state token and input
--        ...
--        ... kf errMsg (if input not OK)
--        ... k s ... (if we get something useful for next parser)
--  @
newtype Parser a = Parser {
        forall a.
Parser a
-> forall r.
   (ParseError -> ParseStep ParseError r)
   -> (State# ParserState -> a -> ParseStep ParseError r)
   -> State# ParserState
   -> ParseStep ParseError r
runParser :: forall r . (ParseError -> ParseStep ParseError r)
                  -> (State# ParserState -> a -> ParseStep ParseError r)
                  -> State# ParserState -> ParseStep ParseError r
    }

-- | State token tag used in `Parser`
data ParserState

-- It seems eta-expand all params to ensure parsers are saturated is helpful
instance Functor Parser where
    fmap :: forall a b. (a -> b) -> Parser a -> Parser b
fmap = forall a b. (a -> b) -> Parser a -> Parser b
fmapParser
    {-# INLINE fmap #-}
    a
a <$ :: forall a b. a -> Parser b -> Parser a
<$ Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' b
_ -> State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s' a
a) State# ParserState
s Bytes
inp)
    {-# INLINE (<$) #-}

fmapParser :: (a -> b) -> Parser a -> Parser b
{-# INLINE fmapParser #-}
fmapParser :: forall a b. (a -> b) -> Parser a -> Parser b
fmapParser a -> b
f (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa) = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' -> State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s' forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) State# ParserState
s Bytes
inp)

instance Applicative Parser where
    pure :: forall a. a -> Parser a
pure a
x = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s a
x Bytes
inp)
    {-# INLINE pure #-}
    <*> :: forall a b. Parser (a -> b) -> Parser a -> Parser b
(<*>) = forall a b. Parser (a -> b) -> Parser a -> Parser b
apParser
    {-# INLINE (<*>) #-}
    Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa *> :: forall a b. Parser a -> Parser b -> Parser b
*> Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' a
_ -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s') State# ParserState
s Bytes
inp)
    {-# INLINE (*>) #-}
    Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa <* :: forall a b. Parser a -> Parser b -> Parser a
<* Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' a
x -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> b -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pb ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s'' b
_ -> State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s'' a
x) State# ParserState
s') State# ParserState
s Bytes
inp)
    {-# INLINE (<*) #-}

apParser :: Parser (a -> b) -> Parser a -> Parser b
{-# INLINE apParser #-}
apParser :: forall a b. Parser (a -> b) -> Parser a -> Parser b
apParser (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> (a -> b) -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pf) (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa) = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> (a -> b) -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pf ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' a -> b
f -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s'' -> State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s'' forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) State# ParserState
s') State# ParserState
s Bytes
inp)

instance Monad Parser where
    return :: forall a. a -> Parser a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure
    {-# INLINE return #-}
    Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa >>= :: forall a b. Parser a -> (a -> Parser b) -> Parser b
>>= a -> Parser b
f = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa ParseError -> ParseStep ParseError r
kf (\ State# ParserState
s' a
a -> forall a.
Parser a
-> forall r.
   (ParseError -> ParseStep ParseError r)
   -> (State# ParserState -> a -> ParseStep ParseError r)
   -> State# ParserState
   -> ParseStep ParseError r
runParser (a -> Parser b
f a
a) ParseError -> ParseStep ParseError r
kf State# ParserState -> b -> ParseStep ParseError r
k State# ParserState
s') State# ParserState
s Bytes
inp)
    {-# INLINE (>>=) #-}
    >> :: forall a b. Parser a -> Parser b -> Parser b
(>>) = forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
    {-# INLINE (>>) #-}

instance PrimMonad Parser where
    type PrimState Parser = ParserState
    {-# INLINE primitive #-}
    primitive :: forall a.
(State# (PrimState Parser) -> (# State# (PrimState Parser), a #))
-> Parser a
primitive State# (PrimState Parser) -> (# State# (PrimState Parser), a #)
io = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
st Bytes
inp ->
        let !(# State# (PrimState Parser)
st', a
r #) = State# (PrimState Parser) -> (# State# (PrimState Parser), a #)
io State# ParserState
st
        in State# ParserState -> a -> ParseStep ParseError r
k State# (PrimState Parser)
st' a
r Bytes
inp)

{-# RULES "replicateM/Parser" forall n (x :: Parser a). V.replicateM n x = V.replicatePM n x #-}
{-# RULES "traverse/Parser" forall (f :: a -> Parser b). V.traverse f = V.traverseWithIndexPM (const f) #-}
{-# RULES "traverseWithIndex/Parser" forall (f :: Int -> a -> Parser b). V.traverseWithIndex f = V.traverseWithIndexPM f #-}

-- | Unsafely lifted an `IO` action into 'Parser'.
--
-- This is only for debugging purpose(logging, etc). Don't mix compuation from
-- realworld to parsing result, otherwise parsing is not deterministic.
unsafeLiftIO :: IO a -> Parser a
{-# INLINE unsafeLiftIO #-}
unsafeLiftIO :: forall a. IO a -> Parser a
unsafeLiftIO (IO State# RealWorld -> (# State# RealWorld, a #)
io) = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
_ State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
st Bytes
inp ->
    let !(# State# RealWorld
st', a
r #) = State# RealWorld -> (# State# RealWorld, a #)
io (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# State# ParserState
st)
    in State# ParserState -> a -> ParseStep ParseError r
k (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# State# RealWorld
st') a
r Bytes
inp

instance Fail.MonadFail Parser where
    fail :: forall a. String -> Parser a
fail = forall a. Text -> Parser a
fail' forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
    {-# INLINE fail #-}

instance MonadPlus Parser where
    mzero :: forall a. Parser a
mzero = forall (f :: * -> *) a. Alternative f => f a
empty
    {-# INLINE mzero #-}
    mplus :: forall a. Parser a -> Parser a -> Parser a
mplus = forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)
    {-# INLINE mplus #-}

instance Alternative Parser where
    empty :: forall a. Parser a
empty = forall a. Text -> Parser a
fail' Text
"Z.Data.Parser.Base(Alternative).empty"
    {-# INLINE empty #-}
    Parser a
f <|> :: forall a. Parser a -> Parser a -> Parser a
<|> Parser a
g = do
        (Result ParseError a
r, Bytes
consumed) <- forall a. Parser a -> Parser (Result ParseError a, Bytes)
runAndKeepTrack Parser a
f
        case Result ParseError a
r of
            Success a
x Bytes
inp   -> forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
_ -> State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s a
x Bytes
inp)
            Failure ParseError
_ Bytes
_     -> forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
_ -> forall a.
Parser a
-> forall r.
   (ParseError -> ParseStep ParseError r)
   -> (State# ParserState -> a -> ParseStep ParseError r)
   -> State# ParserState
   -> ParseStep ParseError r
runParser Parser a
g ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
consumed)
            Result ParseError a
_               -> forall a. (?callStack::CallStack) => String -> a
error String
"Z.Data.Parser.Base: impossible"
    {-# INLINE (<|>) #-}

-- | 'T.Text' version of 'fail'.
fail' :: T.Text -> Parser a
{-# INLINE fail' #-}
fail' :: forall a. Text -> Parser a
fail' Text
msg = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
_ State# ParserState
_ Bytes
inp -> ParseError -> ParseStep ParseError r
kf [Text
msg] Bytes
inp)

-- | Similar to `fail'`, but can produce error message with current input chunk.
failWithInput :: (V.Bytes -> T.Text) -> Parser a
{-# INLINE failWithInput #-}
failWithInput :: forall a. (Bytes -> Text) -> Parser a
failWithInput Bytes -> Text
f = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
_ State# ParserState
_ Bytes
inp -> ParseError -> ParseStep ParseError r
kf [Bytes -> Text
f Bytes
inp] Bytes
inp)

-- | Parse the complete input, without resupplying
parse' :: Parser a -> V.Bytes -> Either ParseError a
{-# INLINABLE parse' #-}
parse' :: forall a. Parser a -> Bytes -> Either ParseError a
parse' Parser a
p = forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Parser a -> Bytes -> (Bytes, Either ParseError a)
parse Parser a
p

-- | Parse the complete input, without resupplying, return the rest bytes
parse :: Parser a -> V.Bytes -> (V.Bytes, Either ParseError a)
{-# INLINE parse #-}
parse :: forall a. Parser a -> Bytes -> (Bytes, Either ParseError a)
parse (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p) = \ Bytes
inp ->
    case (forall o. (State# RealWorld -> o) -> o
runRW# ( \ State# RealWorld
s -> unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# (forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p forall e r. e -> Bytes -> Result e r
Failure (\ State# ParserState
_ a
r -> forall e r. r -> Bytes -> Result e r
Success a
r) (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# State# RealWorld
s) Bytes
inp))) of
        Success a
a Bytes
rest    -> (Bytes
rest, forall a b. b -> Either a b
Right a
a)
        Failure ParseError
errs Bytes
rest -> (Bytes
rest, forall a b. a -> Either a b
Left ParseError
errs)
        Partial ParseStep ParseError a
f         -> forall a. Result ParseError a -> (Bytes, Either ParseError a)
finishParsing (ParseStep ParseError a
f forall (v :: * -> *) a. Vec v a => v a
V.empty)

-- | Parse the complete input list, without resupplying, return the rest bytes list.
--
-- Parsers in "Z.Data.Parser" will take 'V.empty' as EOF, so please make sure there are no 'V.empty's
-- mixed into the chunk list.
parseChunkList :: Parser a -> [V.Bytes] -> ([V.Bytes], Either ParseError a)
{-# INLINABLE parseChunkList #-}
parseChunkList :: forall a. Parser a -> [Bytes] -> ([Bytes], Either ParseError a)
parseChunkList Parser a
p (Bytes
inp:[Bytes]
inps) = forall {a}.
Result ParseError a -> [Bytes] -> ([Bytes], Either ParseError a)
go (forall a. Parser a -> Bytes -> Result ParseError a
parseChunk Parser a
p Bytes
inp) [Bytes]
inps
    where
        go :: Result ParseError a -> [Bytes] -> ([Bytes], Either ParseError a)
go Result ParseError a
r [Bytes]
is = case Result ParseError a
r of
            Partial ParseStep ParseError a
f -> case [Bytes]
is of
                (Bytes
i:[Bytes]
is') -> Result ParseError a -> [Bytes] -> ([Bytes], Either ParseError a)
go (ParseStep ParseError a
f Bytes
i) [Bytes]
is'
                [Bytes]
_ -> let (Bytes
rest, Either ParseError a
r') = forall a. Result ParseError a -> (Bytes, Either ParseError a)
finishParsing Result ParseError a
r
                     in (if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest then [] else [Bytes
rest], Either ParseError a
r')
            Success a
a Bytes
rest    -> (if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest then [Bytes]
is else Bytes
restforall a. a -> [a] -> [a]
:[Bytes]
is, forall a b. b -> Either a b
Right a
a)
            Failure ParseError
errs Bytes
rest -> (if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest then [Bytes]
is else Bytes
restforall a. a -> [a] -> [a]
:[Bytes]
is, forall a b. a -> Either a b
Left ParseError
errs)

-- | Parse an input chunk
parseChunk :: Parser a -> V.Bytes -> Result ParseError a
{-# INLINE parseChunk #-}
parseChunk :: forall a. Parser a -> Bytes -> Result ParseError a
parseChunk (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p) = forall o. (State# RealWorld -> o) -> o
runRW# (\ State# RealWorld
s ->
    unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# (forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p forall e r. e -> Bytes -> Result e r
Failure (\ State# ParserState
_ a
r -> forall e r. r -> Bytes -> Result e r
Success a
r) (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# State# RealWorld
s)))

-- | Finish parsing and fetch result, feed empty bytes if it's 'Partial' result.
finishParsing :: Result ParseError a -> (V.Bytes, Either ParseError a)
{-# INLINABLE finishParsing #-}
finishParsing :: forall a. Result ParseError a -> (Bytes, Either ParseError a)
finishParsing Result ParseError a
r = case Result ParseError a
r of
    Success a
a Bytes
rest    -> (Bytes
rest, forall a b. b -> Either a b
Right a
a)
    Failure ParseError
errs Bytes
rest -> (Bytes
rest, forall a b. a -> Either a b
Left ParseError
errs)
    Partial ParseStep ParseError a
f         -> forall a. Result ParseError a -> (Bytes, Either ParseError a)
finishParsing (ParseStep ParseError a
f forall (v :: * -> *) a. Vec v a => v a
V.empty)

-- | Type alias for a streaming parser, draw chunk from Monad m with a initial chunk,
-- return result in @Either err x@.
type ParseChunks m err x = m V.Bytes -> V.Bytes -> m (V.Bytes, Either err x)

-- | Run a chunk parser with an initial input string, and a monadic action
-- that can supply more input if needed.
--
parseChunks :: Monad m => (V.Bytes -> Result e a) -> ParseChunks m e a
{-# INLINE parseChunks #-}
parseChunks :: forall (m :: * -> *) e a.
Monad m =>
(Bytes -> Result e a) -> ParseChunks m e a
parseChunks Bytes -> Result e a
pc m Bytes
m Bytes
inp = Result e a -> m (Bytes, Either e a)
go (Bytes -> Result e a
pc Bytes
inp)
  where
    go :: Result e a -> m (Bytes, Either e a)
go Result e a
r = case Result e a
r of
        Partial Bytes -> Result e a
f -> Result e a -> m (Bytes, Either e a)
go forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> Result e a
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m Bytes
m
        Success a
a Bytes
rest    -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bytes
rest, forall a b. b -> Either a b
Right a
a)
        Failure e
errs Bytes
rest -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bytes
rest, forall a b. a -> Either a b
Left e
errs)

(<?>) :: T.Text -> Parser a -> Parser a
{-# INLINE (<?>) #-}
Text
msg <?> :: forall a. Text -> Parser a -> Parser a
<?> (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p) = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
p (ParseError -> ParseStep ParseError r
kf forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
msgforall a. a -> [a] -> [a]
:)) State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp)
infixr 0 <?>

-- | Run a parser and keep track of all the input chunks it consumes.
-- Once it's finished, return the final result (always 'Success' or 'Failure') and
-- all consumed chunks.
--
runAndKeepTrack :: Parser a -> Parser (Result ParseError a, V.Bytes)
{-# INLINE runAndKeepTrack #-}
runAndKeepTrack :: forall a. Parser a -> Parser (Result ParseError a, Bytes)
runAndKeepTrack (Parser forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa) = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
_ State# ParserState
-> (Result ParseError a, Bytes) -> ParseStep ParseError r
k0 State# ParserState
st0 Bytes
inp ->
    let go :: [Bytes]
-> Result e r
-> (State# ParserState
    -> (Result e r, Bytes) -> Bytes -> Result e r)
-> State# ParserState
-> Result e r
go ![Bytes]
acc Result e r
r State# ParserState -> (Result e r, Bytes) -> Bytes -> Result e r
k (State# ParserState
st :: State# ParserState) = case Result e r
r of
            Partial ParseStep e r
k'      -> forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' -> [Bytes]
-> Result e r
-> (State# ParserState
    -> (Result e r, Bytes) -> Bytes -> Result e r)
-> State# ParserState
-> Result e r
go (Bytes
inp'forall a. a -> [a] -> [a]
:[Bytes]
acc) (ParseStep e r
k' Bytes
inp') State# ParserState -> (Result e r, Bytes) -> Bytes -> Result e r
k State# ParserState
st)
            Success r
_ Bytes
inp' -> let consumed :: Bytes
consumed = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc in Bytes
consumed seq :: forall a b. a -> b -> b
`seq` State# ParserState -> (Result e r, Bytes) -> Bytes -> Result e r
k State# ParserState
st (Result e r
r, Bytes
consumed) Bytes
inp'
            Failure e
_ Bytes
inp' -> let consumed :: Bytes
consumed = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc in Bytes
consumed seq :: forall a b. a -> b -> b
`seq` State# ParserState -> (Result e r, Bytes) -> Bytes -> Result e r
k State# ParserState
st (Result e r
r, Bytes
consumed) Bytes
inp'
        r0 :: Result ParseError a
r0 = forall o. (State# RealWorld -> o) -> o
runRW# (\ State# RealWorld
s ->
                unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# (forall r.
(ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
pa forall e r. e -> Bytes -> Result e r
Failure (\ State# ParserState
_ a
r -> forall e r. r -> Bytes -> Result e r
Success a
r) (unsafeCoerce# :: forall a b. a -> b
unsafeCoerce# State# RealWorld
s) Bytes
inp))
    in forall {e} {r} {e} {r}.
[Bytes]
-> Result e r
-> (State# ParserState
    -> (Result e r, Bytes) -> Bytes -> Result e r)
-> State# ParserState
-> Result e r
go [Bytes
inp] Result ParseError a
r0 State# ParserState
-> (Result ParseError a, Bytes) -> ParseStep ParseError r
k0 State# ParserState
st0

-- | Return both the result of a parse and the portion of the input
-- that was consumed while it was being parsed.
--
match :: Parser a -> Parser (V.Bytes, a)
{-# INLINE match #-}
match :: forall a. Parser a -> Parser (Bytes, a)
match Parser a
p = do
    (Result ParseError a
r, Bytes
consumed) <- forall a. Parser a -> Parser (Result ParseError a, Bytes)
runAndKeepTrack Parser a
p
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> (Bytes, a) -> ParseStep ParseError r
k State# ParserState
s Bytes
_ ->
        case Result ParseError a
r of
            Success a
r' Bytes
inp'  -> let consumed' :: Bytes
consumed' = forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.dropR (forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp') Bytes
consumed
                                in Bytes
consumed' seq :: forall a b. a -> b -> b
`seq` State# ParserState -> (Bytes, a) -> ParseStep ParseError r
k State# ParserState
s (Bytes
consumed' , a
r') Bytes
inp'
            Failure ParseError
err Bytes
inp' -> forall e r. e -> Bytes -> Result e r
Failure ParseError
err Bytes
inp'
            Partial ParseStep ParseError a
_        -> forall a. (?callStack::CallStack) => String -> a
error String
"Z.Data.Parser.Base.match: impossible")

-- | Ensure that there are at least @n@ bytes available. If not, the
-- computation will escape with 'Partial'.
--
-- Since this parser is used in many other parsers, an extra error param is provide
-- to attach custom error info.
ensureN :: Int -> T.Text -> Parser ()
{-# INLINE ensureN #-}
ensureN :: Int -> Text -> Parser ()
ensureN Int
n0 Text
err = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> do
    let l :: Int
l = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
    if Int
n0 forall a. Ord a => a -> a -> Bool
<= Int
l
    then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
inp
    else forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
Int
-> Bytes
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
ensureNPartial (Int
n0forall a. Num a => a -> a -> a
-Int
l) Bytes
inp ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s)
  where
    ensureNPartial :: forall r. Int -> V.PrimVector Word8 -> (ParseError -> ParseStep ParseError r)
                   -> (State# ParserState -> () -> ParseStep ParseError r)
                   -> State# ParserState -> ParseStep ParseError r
    ensureNPartial :: forall r.
Int
-> Bytes
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
ensureNPartial !Int
l0 Bytes
inp0 ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s0 =
        let go :: [Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc !Int
l State# ParserState
s = \ Bytes
inp -> do
                let l' :: Int
l' = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
                if Int
l' forall a. Eq a => a -> a -> Bool
== Int
0
                then ParseError -> ParseStep ParseError r
kf [Text
err] (forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc))
                else do
                    if Int
l forall a. Ord a => a -> a -> Bool
<= Int
l'
                    then let !inp' :: Bytes
inp' = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc) in State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
inp'
                    else forall e r. (Bytes -> Result e r) -> Result e r
Partial ([Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc) (Int
l forall a. Num a => a -> a -> a
- Int
l') State# ParserState
s)
        in [Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go [Bytes
inp0] Int
l0 State# ParserState
s0

-- | Ensure that there are at least @n@ bytes available. If not, the
-- computation will escape with 'Partial'.
--
-- Since this parser is used in many other parsers, an extra error param is provide
-- to attach custom error info.
readN :: forall a. Int -> T.Text -> (V.Bytes -> a) -> Parser a
{-# INLINE readN #-}
readN :: forall a. Int -> Text -> (Bytes -> a) -> Parser a
readN Int
n0 Text
err Bytes -> a
f = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> do
    let l :: Int
l = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
    if Int
n0 forall a. Ord a => a -> a -> Bool
<= Int
l
    then let !r :: a
r = Bytes -> a
f Bytes
inp
             !inp' :: Bytes
inp' = forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n0 Bytes
inp
             in State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s a
r Bytes
inp'
    else forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
Int
-> Bytes
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
readNPartial (Int
n0forall a. Num a => a -> a -> a
-Int
l) Bytes
inp ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s)
  where
    readNPartial :: forall r. Int -> V.PrimVector Word8 -> (ParseError -> ParseStep ParseError r)
                   -> (State# ParserState -> a -> ParseStep ParseError r)
                   -> State# ParserState -> ParseStep ParseError r
    readNPartial :: forall r.
Int
-> Bytes
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> a -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
readNPartial !Int
l0 Bytes
inp0 ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s0 =
        let go :: [Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc !Int
l State# ParserState
s = \ Bytes
inp -> do
                let l' :: Int
l' = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
                if Int
l' forall a. Eq a => a -> a -> Bool
== Int
0
                then ParseError -> ParseStep ParseError r
kf [Text
err] (forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc))
                else do
                    if Int
l forall a. Ord a => a -> a -> Bool
<= Int
l'
                    then let !inp' :: Bytes
inp' = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc)
                             !r :: a
r  = Bytes -> a
f Bytes
inp'
                             !inp'' :: Bytes
inp'' = forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n0 Bytes
inp'
                         in State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s a
r Bytes
inp''
                    else forall e r. (Bytes -> Result e r) -> Result e r
Partial ([Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc) (Int
l forall a. Num a => a -> a -> a
- Int
l') State# ParserState
s)
        in [Bytes] -> Int -> State# ParserState -> ParseStep ParseError r
go [Bytes
inp0] Int
l0 State# ParserState
s0

{- These rules are bascially what inliner do so no need to mess up with them
{-# RULES "readN/fmap"
    forall n f g e. fmapParser f (readN n e g)  = readN n e (f . g) #-}
{-# RULES "readN/merge"
    forall n1 n2 e1 e2 f1 f2. apParser (readN n1 e1 f1) (readN n2 e2 f2) = readN (n1 + n2) (T.concat [e1, ", ", e2]) (\ inp -> f1 inp $! f2 (V.unsafeDrop n1 inp)) #-}
-}

-- | Get current input chunk, draw new chunk if neccessary. 'V.null' means EOF.
--
-- Note this is different from 'takeRemaining', 'currentChunk' only return what's
-- left in current input chunk.
currentChunk :: Parser V.Bytes
{-# INLINE currentChunk #-}
currentChunk :: Parser Bytes
currentChunk =  forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
_ State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
    if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
    then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' -> State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp' forall (v :: * -> *) a. Vec v a => v a
V.empty)
    else State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp forall (v :: * -> *) a. Vec v a => v a
V.empty

-- | Test whether all input has been consumed, i.e. there are no remaining
-- undecoded bytes. Fail if not 'atEnd'.
endOfInput :: Parser ()
{-# INLINE endOfInput #-}
endOfInput :: Parser ()
endOfInput = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
    if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
    then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' ->
        if (forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp')
        then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
inp'
        else ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.endOfInput: end not reached yet"] Bytes
inp')
    else ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.endOfInput: end not reached yet"] Bytes
inp

-- | Test whether all input has been consumed, i.e. there are no remaining
-- undecoded bytes.
atEnd :: Parser Bool
{-# INLINE atEnd #-}
atEnd :: Parser Bool
atEnd = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
_ State# ParserState -> Bool -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
    if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
    then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' -> State# ParserState -> Bool -> ParseStep ParseError r
k State# ParserState
s (forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp') Bytes
inp')
    else State# ParserState -> Bool -> ParseStep ParseError r
k State# ParserState
s Bool
False Bytes
inp

-- | Decode a primitive type in host byte order.
decodePrim :: forall a. (Unaligned a) => Parser a
{-# INLINE decodePrim #-}
decodePrim :: forall a. Unaligned a => Parser a
decodePrim = do
    forall a. Int -> Text -> (Bytes -> a) -> Parser a
readN Int
n Text
"Z.Data.Parser.Base.decodePrim: not enough bytes" (\ (V.PrimVector PrimArray Word8
ba Int
i Int
_) -> forall a. Unaligned a => PrimArray Word8 -> Int -> a
indexPrimWord8ArrayAs PrimArray Word8
ba Int
i)
  where
    n :: Int
n = forall {k} (a :: k). UnalignedSize a -> Int
getUnalignedSize (forall a. Unaligned a => UnalignedSize a
unalignedSize @a)

#define DECODE_HOST(f, type) \
    f :: Parser type; {-# INLINE f #-}; f = decodePrim; \
    -- ^ Decode type in host endian order.

DECODE_HOST(decodeWord  , Word   )
DECODE_HOST(decodeWord64, Word64 )
DECODE_HOST(decodeWord32, Word32 )
DECODE_HOST(decodeWord16, Word16 )
DECODE_HOST(decodeWord8 , Word8  )
DECODE_HOST(decodeInt   , Int    )
DECODE_HOST(decodeInt64 , Int64  )
DECODE_HOST(decodeInt32 , Int32  )
DECODE_HOST(decodeInt16 , Int16  )
DECODE_HOST(decodeInt8  , Int8   )
DECODE_HOST(decodeDouble, Double )
DECODE_HOST(decodeFloat , Float  )

-- | Decode a primitive type in little endian.
decodePrimLE :: forall a. (Unaligned (LE a)) => Parser a
{-# INLINE decodePrimLE #-}
decodePrimLE :: forall a. Unaligned (LE a) => Parser a
decodePrimLE = do
    forall a. Int -> Text -> (Bytes -> a) -> Parser a
readN Int
n Text
"Z.Data.Parser.Base.decodePrimLE: not enough bytes" (\ (V.PrimVector PrimArray Word8
ba Int
i Int
_) -> forall a. LE a -> a
getLE (forall a. Unaligned a => PrimArray Word8 -> Int -> a
indexPrimWord8ArrayAs PrimArray Word8
ba Int
i))
  where
    n :: Int
n = forall {k} (a :: k). UnalignedSize a -> Int
getUnalignedSize (forall a. Unaligned a => UnalignedSize a
unalignedSize @(LE a))

#define DECODE_LE(f, type) \
    f :: Parser type; {-# INLINE f #-}; f = decodePrimLE; \
    -- ^ Decode type in little endian order.

DECODE_LE(decodeWordLE  , Word   )
DECODE_LE(decodeWord64LE, Word64 )
DECODE_LE(decodeWord32LE, Word32 )
DECODE_LE(decodeWord16LE, Word16 )
DECODE_LE(decodeIntLE   , Int    )
DECODE_LE(decodeInt64LE , Int64  )
DECODE_LE(decodeInt32LE , Int32  )
DECODE_LE(decodeInt16LE , Int16  )
DECODE_LE(decodeDoubleLE, Double )
DECODE_LE(decodeFloatLE , Float  )

-- | Decode a primitive type in big endian.
decodePrimBE :: forall a. (Unaligned (BE a)) => Parser a
{-# INLINE decodePrimBE #-}
decodePrimBE :: forall a. Unaligned (BE a) => Parser a
decodePrimBE = do
    forall a. Int -> Text -> (Bytes -> a) -> Parser a
readN Int
n Text
"Z.Data.Parser.Base.decodePrimBE: not enough bytes" (\ (V.PrimVector PrimArray Word8
ba Int
i Int
_) -> forall a. BE a -> a
getBE (forall a. Unaligned a => PrimArray Word8 -> Int -> a
indexPrimWord8ArrayAs PrimArray Word8
ba Int
i))
  where
    n :: Int
n = forall {k} (a :: k). UnalignedSize a -> Int
getUnalignedSize (forall a. Unaligned a => UnalignedSize a
unalignedSize @(BE a))

#define DECODE_BE(f, type) \
    f :: Parser type; {-# INLINE f #-}; f = decodePrimBE; \
    -- ^ Decode type in big endian order.

DECODE_BE(decodeWordBE  , Word   )
DECODE_BE(decodeWord64BE, Word64 )
DECODE_BE(decodeWord32BE, Word32 )
DECODE_BE(decodeWord16BE, Word16 )
DECODE_BE(decodeIntBE   , Int    )
DECODE_BE(decodeInt64BE , Int64  )
DECODE_BE(decodeInt32BE , Int32  )
DECODE_BE(decodeInt16BE , Int16  )
DECODE_BE(decodeDoubleBE, Double )
DECODE_BE(decodeFloatBE , Float  )

-- | A stateful scanner.  The predicate consumes and transforms a
-- state argument, and each transformed state is passed to successive
-- invocations of the predicate on each byte of the input until one
-- returns 'Nothing' or the input ends.
--
-- This parser does not fail.  It will return an empty string if the
-- predicate returns 'Nothing' on the first byte of input.
--
scan :: s -> (s -> Word8 -> Maybe s) -> Parser (V.Bytes, s)
{-# INLINE scan #-}
scan :: forall s. s -> (s -> Word8 -> Maybe s) -> Parser (Bytes, s)
scan s
s0 s -> Word8 -> Maybe s
f = forall s.
s
-> (s -> Bytes -> Either s (Bytes, Bytes, s)) -> Parser (Bytes, s)
scanChunks s
s0 s -> Bytes -> Either s (Bytes, Bytes, s)
f'
  where
    f' :: s -> Bytes -> Either s (Bytes, Bytes, s)
f' s
s0' (V.PrimVector PrimArray Word8
arr Int
off Int
l) =
        let !end :: Int
end = Int
off forall a. Num a => a -> a -> a
+ Int
l
            go :: s -> Int -> Either s (Bytes, Bytes, s)
go !s
st !Int
i
                | Int
i forall a. Ord a => a -> a -> Bool
< Int
end = do
                    let !w :: Word8
w = forall a. Prim a => PrimArray a -> Int -> a
A.indexPrimArray PrimArray Word8
arr Int
i
                    case s -> Word8 -> Maybe s
f s
st Word8
w of
                        Just s
st' -> s -> Int -> Either s (Bytes, Bytes, s)
go s
st' (Int
iforall a. Num a => a -> a -> a
+Int
1)
                        Maybe s
_        ->
                            let !len1 :: Int
len1 = Int
i forall a. Num a => a -> a -> a
- Int
off
                                !len2 :: Int
len2 = Int
end forall a. Num a => a -> a -> a
- Int
off
                            in forall a b. b -> Either a b
Right (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
off Int
len1, forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
i Int
len2, s
st)
                | Bool
otherwise = forall a b. a -> Either a b
Left s
st
        in s -> Int -> Either s (Bytes, Bytes, s)
go s
s0' Int
off

-- | Similar to 'scan', but working on 'V.Bytes' chunks, The predicate
-- consumes a 'V.Bytes' chunk and transforms a state argument,
-- and each transformed state is passed to successive invocations of
-- the predicate on each chunk of the input until one chunk got splited to
-- @Right (V.Bytes, V.Bytes)@ or the input ends.
--
-- Note the fields of result triple will not be forced by 'scanChunks', you may need to add `seq` or strict annotation to
-- avoid thunks and unintentional references to buffer.
--
scanChunks :: forall s. s -> (s -> V.Bytes -> Either s (V.Bytes, V.Bytes, s)) -> Parser (V.Bytes, s)
{-# INLINE scanChunks #-}
scanChunks :: forall s.
s
-> (s -> Bytes -> Either s (Bytes, Bytes, s)) -> Parser (Bytes, s)
scanChunks s
s0 s -> Bytes -> Either s (Bytes, Bytes, s)
consume = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st Bytes
inp ->
    case s -> Bytes -> Either s (Bytes, Bytes, s)
consume s
s0 Bytes
inp of
        Right (Bytes
want, Bytes
rest, s
s') -> State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st (Bytes
want, s
s') Bytes
rest
        Left s
s' -> forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
s
-> (State# ParserState -> (Bytes, s) -> ParseStep ParseError r)
-> State# ParserState
-> Bytes
-> ParseStep ParseError r
scanChunksPartial s
s' State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st Bytes
inp))
  where
    -- we want to inline consume if possible
    {-# INLINE scanChunksPartial #-}
    scanChunksPartial :: forall r. s -> (State# ParserState -> (V.PrimVector Word8, s) -> ParseStep ParseError r)
                      -> State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r
    scanChunksPartial :: forall r.
s
-> (State# ParserState -> (Bytes, s) -> ParseStep ParseError r)
-> State# ParserState
-> Bytes
-> ParseStep ParseError r
scanChunksPartial s
s0' State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st0 Bytes
inp0 =
        let go :: s -> [Bytes] -> State# ParserState -> ParseStep ParseError r
go s
s [Bytes]
acc State# ParserState
st = \ Bytes
inp ->
                if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
                then State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st (forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc, s
s) Bytes
inp
                else case s -> Bytes -> Either s (Bytes, Bytes, s)
consume s
s Bytes
inp of
                        Left s
s' -> do
                            let acc' :: [Bytes]
acc' = Bytes
inp forall a. a -> [a] -> [a]
: [Bytes]
acc
                            forall e r. (Bytes -> Result e r) -> Result e r
Partial (s -> [Bytes] -> State# ParserState -> ParseStep ParseError r
go s
s' [Bytes]
acc' State# ParserState
st)
                        Right (Bytes
want,Bytes
rest,s
s') ->
                            let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR (Bytes
wantforall a. a -> [a] -> [a]
:[Bytes]
acc) in State# ParserState -> (Bytes, s) -> ParseStep ParseError r
k State# ParserState
st (Bytes
r, s
s') Bytes
rest
        in s -> [Bytes] -> State# ParserState -> ParseStep ParseError r
go s
s0' [Bytes
inp0] State# ParserState
st0

--------------------------------------------------------------------------------

-- | Match any byte, to perform lookahead. Returns 'Nothing' if end of
-- input has been reached. Does not consume any input.
--
peekMaybe :: Parser (Maybe Word8)
{-# INLINE peekMaybe #-}
peekMaybe :: Parser (Maybe Word8)
peekMaybe =
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
_ State# ParserState -> Maybe Word8 -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
        then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' -> State# ParserState -> Maybe Word8 -> ParseStep ParseError r
k State# ParserState
s (if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp'
            then forall a. Maybe a
Nothing
            else forall a. a -> Maybe a
Just (forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp')) Bytes
inp')
        else State# ParserState -> Maybe Word8 -> ParseStep ParseError r
k State# ParserState
s (forall a. a -> Maybe a
Just (forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp)) Bytes
inp

-- | Match any byte, to perform lookahead.  Does not consume any
-- input, but will fail if end of input has been reached.
--
peek :: Parser Word8
{-# INLINE peek #-}
peek :: Parser Word8
peek =
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> Word8 -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
        then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' ->
            if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp'
            then ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.peek: not enough bytes"] Bytes
inp'
            else State# ParserState -> Word8 -> ParseStep ParseError r
k State# ParserState
s (forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp') Bytes
inp')
        else State# ParserState -> Word8 -> ParseStep ParseError r
k State# ParserState
s (forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp) Bytes
inp

-- | The parser @satisfy p@ succeeds for any byte for which the
-- predicate @p@ returns 'True'. Returns the byte that is actually
-- parsed.
--
-- >digit = satisfy isDigit
-- >    where isDigit w = w >= 48 && w <= 57
--
satisfy :: (Word8 -> Bool) -> Parser Word8
{-# INLINE satisfy #-}
satisfy :: (Word8 -> Bool) -> Parser Word8
satisfy Word8 -> Bool
p = do
    Int -> Text -> Parser ()
ensureN Int
1 Text
"Z.Data.Parser.Base.satisfy: not enough bytes"
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> Word8 -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        let w :: Word8
w = forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp
        in if Word8 -> Bool
p Word8
w
            then State# ParserState -> Word8 -> ParseStep ParseError r
k State# ParserState
s Word8
w (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)
            else ParseError -> ParseStep ParseError r
kf [ Text
"Z.Data.Parser.Base.satisfy: unsatisfied bytes " forall a. Semigroup a => a -> a -> a
<> forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
8 Bytes
inp) ]
                    (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)

-- | The parser @satisfyWith f p@ transforms a byte, and succeeds if
-- the predicate @p@ returns 'True' on the transformed value. The
-- parser returns the transformed byte that was parsed.
--
satisfyWith :: (Word8 -> a) -> (a -> Bool) -> Parser a
{-# INLINE satisfyWith #-}
satisfyWith :: forall a. (Word8 -> a) -> (a -> Bool) -> Parser a
satisfyWith Word8 -> a
f a -> Bool
p = do
    Int -> Text -> Parser ()
ensureN Int
1 Text
"Z.Data.Parser.Base.satisfyWith: not enough bytes"
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        let a :: a
a = Word8 -> a
f (forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp)
        in if a -> Bool
p a
a
            then State# ParserState -> a -> ParseStep ParseError r
k State# ParserState
s a
a (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)
            else ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.satisfyWith: unsatisfied byte"] (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)

-- | Match a specific byte.
--
word8 :: Word8 -> Parser ()
{-# INLINE word8 #-}
word8 :: Word8 -> Parser ()
word8 Word8
w' = do
    Int -> Text -> Parser ()
ensureN Int
1 Text
"Z.Data.Parser.Base.word8: not enough bytes"
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        let w :: Word8
w = forall (v :: * -> *) a. Vec v a => v a -> a
V.unsafeHead Bytes
inp
        in if Word8
w forall a. Eq a => a -> a -> Bool
== Word8
w'
            then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)
            else ParseError -> ParseStep ParseError r
kf [ ParseError -> Text
T.concat [
                 Text
"Z.Data.Parser.Base.word8: mismatch byte, expected "
                , forall a. Print a => a -> Text
T.toText Word8
w'
                , Text
", meet "
                , forall a. Print a => a -> Text
T.toText Word8
w
                , Text
" at "
                , forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
8 Bytes
inp)
                ] ] Bytes
inp)

-- | Return a byte, this is an alias to @decodePrim @Word8@.
--
anyWord8 :: Parser Word8
{-# INLINE anyWord8 #-}
anyWord8 :: Parser Word8
anyWord8 = forall a. Unaligned a => Parser a
decodePrim

-- | Match a specific 8bit char.
--
char8 :: Char -> Parser ()
{-# INLINE char8 #-}
char8 :: Char -> Parser ()
char8 = Word8 -> Parser ()
word8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Word8
c2w

-- | Match a specific 7bit char.
--
char7 :: Char -> Parser ()
{-# INLINE char7 #-}
char7 :: Char -> Parser ()
char7 Char
chr = Word8 -> Parser ()
word8 (Char -> Word8
c2w Char
chr forall a. Bits a => a -> a -> a
.&. Word8
0x7F)

-- | Match a specific UTF8 char.
--
charUTF8 :: Char -> Parser ()
{-# INLINE charUTF8 #-}
charUTF8 :: Char -> Parser ()
charUTF8 = Text -> Parser ()
text forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Text
T.singleton

-- | Take a byte and return as a 8bit char.
--
anyChar8 :: Parser Char
{-# INLINE anyChar8 #-}
anyChar8 :: Parser Char
anyChar8 = do
    Word8
w <- Parser Word8
anyWord8
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Word8 -> Char
w2c Word8
w

-- | Take a byte and return as a 7bit char, fail if exceeds @0x7F@.
--
anyChar7 :: Parser Char
{-# INLINE anyChar7 #-}
anyChar7 :: Parser Char
anyChar7 = do
    Word8
w <- (Word8 -> Bool) -> Parser Word8
satisfy (forall a. Ord a => a -> a -> Bool
<= Word8
0x7f)
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Word8 -> Char
w2c Word8
w

-- | Decode next few bytes as an UTF8 char.
--
-- Don't use this method as UTF8 decoder, it's slower than 'T.validate'.
anyCharUTF8 :: Parser Char
{-# INLINE anyCharUTF8 #-}
anyCharUTF8 :: Parser Char
anyCharUTF8 = do
    Either Int Char
r <- forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> Either Int Char -> ParseStep ParseError r
k State# ParserState
st inp :: Bytes
inp@(V.PrimVector PrimArray Word8
arr Int
s Int
l) -> do
        if Int
l forall a. Ord a => a -> a -> Bool
> Int
0
        then
            let l' :: Int
l' = PrimArray Word8 -> Int -> Int
T.decodeCharLen PrimArray Word8
arr Int
s
            in if Int
l' forall a. Ord a => a -> a -> Bool
> Int
l
            then State# ParserState -> Either Int Char -> ParseStep ParseError r
k State# ParserState
st (forall a b. a -> Either a b
Left Int
l') Bytes
inp
            else do
                case Bytes -> Maybe Text
T.validateMaybe (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
l' Bytes
inp) of
                    Just Text
t -> State# ParserState -> Either Int Char -> ParseStep ParseError r
k State# ParserState
st (forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$! Text -> Char
T.head Text
t) forall a b. (a -> b) -> a -> b
$! forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
l' Bytes
inp
                    Maybe Text
_ -> ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.anyCharUTF8: invalid UTF8 bytes"] Bytes
inp
        else State# ParserState -> Either Int Char -> ParseStep ParseError r
k State# ParserState
st (forall a b. a -> Either a b
Left Int
1) Bytes
inp
    case Either Int Char
r of
        Left Int
d -> do
            Int -> Text -> Parser ()
ensureN Int
d Text
"Z.Data.Parser.Base.anyCharUTF8: not enough bytes"
            Parser Char
anyCharUTF8
        Right Char
c -> forall (m :: * -> *) a. Monad m => a -> m a
return Char
c

-- | Match either a single newline byte @\'\\n\'@, or a carriage
-- return followed by a newline byte @\"\\r\\n\"@.
endOfLine :: Parser ()
{-# INLINE endOfLine #-}
endOfLine :: Parser ()
endOfLine = do
    Word8
w <- forall a. Unaligned a => Parser a
decodePrim :: Parser Word8
    case Word8
w of
        Word8
10 -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Word8
13 -> Word8 -> Parser ()
word8 Word8
10

        Word8
_  -> forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
_ State# ParserState
_ Bytes
inp -> ParseError -> ParseStep ParseError r
kf [
            ParseError -> Text
T.concat [
             Text
"Z.Data.Parser.Base.endOfLine: mismatch byte, expected 10 or 13, meet "
            , forall a. Print a => a -> Text
T.toText Word8
w
            , Text
" at "
            , forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => a -> v a -> v a
V.cons Word8
w (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
8 Bytes
inp))
            ] ] Bytes
inp)

--------------------------------------------------------------------------------

-- | 'skip' N bytes.
--
skip :: Int -> Parser ()
{-# INLINE skip #-}
skip :: Int -> Parser ()
skip Int
n = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
n forall a. Ord a => a -> a -> Bool
> Int
0) forall a b. (a -> b) -> a -> b
$
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        let l :: Int
l = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
        in if Int
l forall a. Ord a => a -> a -> Bool
>= Int
n
            then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () forall a b. (a -> b) -> a -> b
$! forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n Bytes
inp
            else forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
Int
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
skipPartial (Int
nforall a. Num a => a -> a -> a
-Int
l) ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s))
  where
    skipPartial :: Int -> (ParseError -> ParseStep ParseError r)
                -> (State# ParserState -> () -> ParseStep ParseError r)
                -> State# ParserState -> ParseStep ParseError r
    skipPartial :: forall r.
Int
-> (ParseError -> ParseStep ParseError r)
-> (State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState
-> ParseStep ParseError r
skipPartial Int
n0 ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s0 =
        let go :: Int -> State# ParserState -> ParseStep ParseError r
go !Int
n' State# ParserState
s = \ Bytes
inp ->
                let l :: Int
l = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
inp
                in if Int
l forall a. Ord a => a -> a -> Bool
>= Int
n'
                    then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () forall a b. (a -> b) -> a -> b
$! forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n' Bytes
inp
                    else if Int
l forall a. Eq a => a -> a -> Bool
== Int
0
                        then ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.skip: not enough bytes"] Bytes
inp
                        else forall e r. (Bytes -> Result e r) -> Result e r
Partial (Int -> State# ParserState -> ParseStep ParseError r
go (Int
n'forall a. Num a => a -> a -> a
-Int
l) State# ParserState
s)
        in Int -> State# ParserState -> ParseStep ParseError r
go Int
n0 State# ParserState
s0

-- | Skip a byte.
--
skipWord8 :: Parser ()
{-# INLINE skipWord8 #-}
skipWord8 :: Parser ()
skipWord8 =
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser forall a b. (a -> b) -> a -> b
$ \ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
        then forall e r. (Bytes -> Result e r) -> Result e r
Partial (\ Bytes
inp' ->
            if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp'
            then ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.skipWord8: not enough bytes"] Bytes
inp'
            else State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp'))
        else State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () (forall (v :: * -> *) a. Vec v a => v a -> v a
V.unsafeTail Bytes
inp)

-- | Skip past input for as long as the predicate returns 'True'.
--
skipWhile :: (Word8 -> Bool) -> Parser ()
{-# INLINE skipWhile #-}
skipWhile :: (Word8 -> Bool) -> Parser ()
skipWhile Word8 -> Bool
p =
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        let !rest :: Bytes
rest = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> v a
V.dropWhile Word8 -> Bool
p Bytes
inp
        in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest
            then forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
(State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState -> ParseStep ParseError r
skipWhilePartial State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s)
            else State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
rest)
  where
    skipWhilePartial :: forall r. (State# ParserState -> () -> ParseStep ParseError r)
                     -> State# ParserState -> ParseStep ParseError r
    skipWhilePartial :: forall r.
(State# ParserState -> () -> ParseStep ParseError r)
-> State# ParserState -> ParseStep ParseError r
skipWhilePartial State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s0 =
        let go :: State# ParserState -> ParseStep ParseError r
go State# ParserState
s = \ Bytes
inp ->
                if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
                then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
inp
                else
                    let !rest :: Bytes
rest = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> v a
V.dropWhile Word8 -> Bool
p Bytes
inp
                    in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest then forall e r. (Bytes -> Result e r) -> Result e r
Partial (State# ParserState -> ParseStep ParseError r
go State# ParserState
s) else State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () Bytes
rest
        in State# ParserState -> ParseStep ParseError r
go State# ParserState
s0

-- | Skip over white space using 'isSpace'.
--
skipSpaces :: Parser ()
{-# INLINE skipSpaces #-}
skipSpaces :: Parser ()
skipSpaces = (Word8 -> Bool) -> Parser ()
skipWhile Word8 -> Bool
isSpace

-- | Take N bytes.
take :: Int -> Parser V.Bytes
{-# INLINE take #-}
take :: Int -> Parser Bytes
take Int
n = forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
n forall a. Ord a => a -> a -> Bool
> Int
0) forall a b. (a -> b) -> a -> b
$ forall a. Int -> Text -> (Bytes -> a) -> Parser a
readN Int
n Text
"Z.Data.Parser.Base.take: not enough bytes" (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
n)

-- | Consume input as long as the predicate returns 'False' or reach the end of input,
-- and return the consumed input.
--
takeTill :: (Word8 -> Bool) -> Parser V.Bytes
{-# INLINE takeTill #-}
takeTill :: (Word8 -> Bool) -> Parser Bytes
takeTill Word8 -> Bool
p = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
    let (!Bytes
want, !Bytes
rest) = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> (v a, v a)
V.break Word8 -> Bool
p Bytes
inp
    in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest
        then forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeTillPartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
want)
        else State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
want Bytes
rest)
  where
    takeTillPartial :: forall r. (State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r)
                    -> State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r
    takeTillPartial :: forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeTillPartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s0 Bytes
want =
        let go :: [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc State# ParserState
s = \ Bytes
inp ->
                if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
                then let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc in State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
r Bytes
inp
                else
                    let (!Bytes
want', !Bytes
rest) = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> (v a, v a)
V.break Word8 -> Bool
p Bytes
inp
                        acc' :: [Bytes]
acc' = Bytes
want' forall a. a -> [a] -> [a]
: [Bytes]
acc
                    in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest
                        then forall e r. (Bytes -> Result e r) -> Result e r
Partial ([Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc' State# ParserState
s)
                        else let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc' in State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
r Bytes
rest
        in [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes
want] State# ParserState
s0

-- | Consume input as long as the predicate returns 'True' or reach the end of input,
-- and return the consumed input.
--
takeWhile :: (Word8 -> Bool) -> Parser V.Bytes
{-# INLINE takeWhile #-}
takeWhile :: (Word8 -> Bool) -> Parser Bytes
takeWhile Word8 -> Bool
p = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
    let (!Bytes
want, !Bytes
rest) = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> (v a, v a)
V.span Word8 -> Bool
p Bytes
inp
    in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest
        then forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeWhilePartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
want)
        else State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
want Bytes
rest)
  where
    takeWhilePartial :: forall r. (State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r)
                     -> State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r
    takeWhilePartial :: forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeWhilePartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s0 Bytes
want =
        let go :: [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc State# ParserState
s = \ Bytes
inp ->
                if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
                then let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc in State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
r Bytes
inp
                else
                    let (!Bytes
want', !Bytes
rest) = forall (v :: * -> *) a. Vec v a => (a -> Bool) -> v a -> (v a, v a)
V.span Word8 -> Bool
p Bytes
inp
                        acc' :: [Bytes]
acc' = Bytes
want' forall a. a -> [a] -> [a]
: [Bytes]
acc
                    in if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
rest
                        then forall e r. (Bytes -> Result e r) -> Result e r
Partial ([Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc' State# ParserState
s)
                        else let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc' in State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
r Bytes
rest
        in [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes
want] State# ParserState
s0

-- | Similar to 'takeWhile', but requires the predicate to succeed on at least one byte
-- of input: it will fail if the predicate never returns 'True' or reach the end of input
--
takeWhile1 :: (Word8 -> Bool) -> Parser V.Bytes
{-# INLINE takeWhile1 #-}
takeWhile1 :: (Word8 -> Bool) -> Parser Bytes
takeWhile1 Word8 -> Bool
p = do
    Bytes
bs <- (Word8 -> Bool) -> Parser Bytes
takeWhile Word8 -> Bool
p
    if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
bs
    then forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> Bytes -> ParseStep ParseError r
_ State# ParserState
_ Bytes
inp ->
            ParseError -> ParseStep ParseError r
kf [Text
"Z.Data.Parser.Base.takeWhile1: no satisfied byte at " forall a. Semigroup a => a -> a -> a
<> forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
10 Bytes
inp) ]
               Bytes
inp)
    else forall (m :: * -> *) a. Monad m => a -> m a
return Bytes
bs

-- | Take all the remaining input chunks and return as 'V.Bytes'.
takeRemaining :: Parser V.Bytes
{-# INLINE takeRemaining #-}
takeRemaining :: Parser Bytes
takeRemaining = forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
_ State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp -> forall e r. (Bytes -> Result e r) -> Result e r
Partial (forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeRemainingPartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
inp))
  where
    takeRemainingPartial :: forall r. (State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r)
                         -> State# ParserState -> V.PrimVector Word8 -> ParseStep ParseError r
    takeRemainingPartial :: forall r.
(State# ParserState -> Bytes -> ParseStep ParseError r)
-> State# ParserState -> Bytes -> ParseStep ParseError r
takeRemainingPartial State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s0 Bytes
want =
        let go :: [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes]
acc State# ParserState
s = \ Bytes
inp ->
                if forall (v :: * -> *) a. Vec v a => v a -> Bool
V.null Bytes
inp
                then let !r :: Bytes
r = forall (v :: * -> *) a. Vec v a => [v a] -> v a
V.concatR [Bytes]
acc in State# ParserState -> Bytes -> ParseStep ParseError r
k State# ParserState
s Bytes
r Bytes
inp
                else forall e r. (Bytes -> Result e r) -> Result e r
Partial ([Bytes] -> State# ParserState -> ParseStep ParseError r
go (Bytes
inpforall a. a -> [a] -> [a]
:[Bytes]
acc) State# ParserState
s)
        in [Bytes] -> State# ParserState -> ParseStep ParseError r
go [Bytes
want] State# ParserState
s0

-- | Take N bytes and validate as UTF8, failed if not UTF8 encoded.
takeUTF8 :: Int -> Parser T.Text
{-# INLINE takeUTF8 #-}
takeUTF8 :: Int -> Parser Text
takeUTF8 Int
n = do
    Bytes
bs <- Int -> Parser Bytes
take Int
n
    case Bytes -> Maybe Text
T.validateMaybe Bytes
bs of Just Text
t -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
t
                               Maybe Text
_ -> forall a. Text -> Parser a
fail' forall a b. (a -> b) -> a -> b
$ Text
"Z.Data.Parser.Base.takeUTF8: illegal UTF8 bytes: " forall a. Semigroup a => a -> a -> a
<> forall a. Print a => a -> Text
T.toText Bytes
bs

-- | Similar to 'take', but requires the predicate to succeed on next N bytes
-- of input, and take N bytes(no matter if N+1 byte satisfy predicate or not).
--
takeN :: (Word8 -> Bool) -> Int -> Parser V.Bytes
{-# INLINE takeN #-}
takeN :: (Word8 -> Bool) -> Int -> Parser Bytes
takeN Word8 -> Bool
p Int
n = do
    Bytes
bs <- Int -> Parser Bytes
take Int
n
    if Bytes -> Int -> Bool
go Bytes
bs Int
0
    then forall (m :: * -> *) a. Monad m => a -> m a
return Bytes
bs
    else forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> Bytes -> ParseStep ParseError r
_ State# ParserState
_ Bytes
inp ->
        ParseError -> ParseStep ParseError r
kf [ Text
"Z.Data.Parser.Base.takeN: byte does not satisfy at " forall a. Semigroup a => a -> a -> a
<> forall a. Print a => a -> Text
T.toText (Bytes
bs forall a. Semigroup a => a -> a -> a
<> forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
10 Bytes
inp) ]
            Bytes
inp)

  where
    go :: Bytes -> Int -> Bool
go bs :: Bytes
bs@(V.PrimVector PrimArray Word8
_ Int
_ Int
l) !Int
i
        | Int
i forall a. Ord a => a -> a -> Bool
< Int
l = Word8 -> Bool
p (forall (v :: * -> *) a. Vec v a => v a -> Int -> a
V.unsafeIndex Bytes
bs Int
i) Bool -> Bool -> Bool
&& Bytes -> Int -> Bool
go Bytes
bs (Int
iforall a. Num a => a -> a -> a
+Int
1)
        | Bool
otherwise = Bool
True

-- | @bytes s@ parses a sequence of bytes that identically match @s@.
--
bytes :: V.Bytes -> Parser ()
{-# INLINE bytes #-}
bytes :: Bytes -> Parser ()
bytes Bytes
bs = do
    let n :: Int
n = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
bs
    Int -> Text -> Parser ()
ensureN Int
n Text
"Z.Data.Parser.Base.bytes: not enough bytes"
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        if Bytes
bs forall a. Eq a => a -> a -> Bool
== forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
n Bytes
inp
        then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () forall a b. (a -> b) -> a -> b
$! forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n Bytes
inp
        else ParseError -> ParseStep ParseError r
kf [ ParseError -> Text
T.concat [
             Text
"Z.Data.Parser.Base.bytes: mismatch bytes, expected "
            , forall a. Print a => a -> Text
T.toText Bytes
bs
            , Text
", meet "
            , forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.take Int
n Bytes
inp)
            ] ] Bytes
inp)


-- | Same as 'bytes' but ignoring ASCII case.
bytesCI :: V.Bytes -> Parser ()
{-# INLINE bytesCI #-}
bytesCI :: Bytes -> Parser ()
bytesCI Bytes
bs = do
    let n :: Int
n = forall (v :: * -> *) a. Vec v a => v a -> Int
V.length Bytes
bs
    -- casefold an ASCII string should not change it's length
    Int -> Text -> Parser ()
ensureN Int
n Text
"Z.Data.Parser.Base.bytesCI: not enough bytes"
    forall a.
(forall r.
 (ParseError -> ParseStep ParseError r)
 -> (State# ParserState -> a -> ParseStep ParseError r)
 -> State# ParserState
 -> ParseStep ParseError r)
-> Parser a
Parser (\ ParseError -> ParseStep ParseError r
kf State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s Bytes
inp ->
        if Bytes
bs' forall a. Eq a => a -> a -> Bool
== forall s. FoldCase s => s -> s
CI.foldCase (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
n Bytes
inp)
        then State# ParserState -> () -> ParseStep ParseError r
k State# ParserState
s () forall a b. (a -> b) -> a -> b
$! forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeDrop Int
n Bytes
inp
        else ParseError -> ParseStep ParseError r
kf [ ParseError -> Text
T.concat [
             Text
"Z.Data.Parser.Base.bytesCI: mismatch bytes, expected "
            , forall a. Print a => a -> Text
T.toText Bytes
bs
            , Text
"(case insensitive), meet "
            , forall a. Print a => a -> Text
T.toText (forall (v :: * -> *) a. Vec v a => Int -> v a -> v a
V.unsafeTake Int
n Bytes
inp)
            ] ] Bytes
inp)

  where
    bs' :: Bytes
bs' = forall s. FoldCase s => s -> s
CI.foldCase Bytes
bs

-- | @text s@ parses a sequence of UTF8 bytes that identically match @s@.
--
text :: T.Text -> Parser ()
{-# INLINE text #-}
text :: Text -> Parser ()
text (T.Text Bytes
bs) = Bytes -> Parser ()
bytes Bytes
bs