{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GADTSyntax #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UnboxedTuples #-}

{- | Parse non-resumable sequence of bytes. To parse a byte sequence
as text, use the @Ascii@, @Latin@, and @Utf8@ modules instead.
Functions for parsing decimal-encoded numbers are found in those
modules.
-}
module Data.Bytes.Parser
  ( -- * Types
    Parser
  , Result (..)
  , Slice (..)

    -- * Run Parsers

    -- ** Result
  , parseByteArray
  , parseBytes
  , parseBytesEffectfully
  , parseBytesEither
  , parseBytesMaybe

    -- * One Byte
  , any

    -- * Many Bytes
  , take
  , takeN
  , takeUpTo
  , takeWhile
  , takeTrailedBy

    -- * Skip
  , skipWhile
  , skipTrailedBy
  , skipTrailedBy2
  , skipTrailedBy2#
  , skipTrailedBy3#

    -- * Match
  , byteArray
  , bytes
  , satisfy
  , satisfyWith
  , cstring

    -- * End of Input
  , endOfInput
  , isEndOfInput
  , remaining
  , peekRemaining

    -- * Scanning
  , scan

    -- * Lookahead
  , peek
  , peek'

    -- * Control Flow
  , fail
  , orElse
  , annotate
  , (<?>)
  , mapErrorEffectfully

    -- * Repetition
  , replicate

    -- * Subparsing
  , delimit
  , measure
  , measure_
  , measure_#

    -- * Lift Effects
  , effect

    -- * Box Result
  , boxWord32
  , boxIntPair

    -- * Unbox Result
  , unboxWord32
  , unboxIntPair

    -- * Specialized Bind

    -- | Sometimes, GHC ends up building join points in a way that
    -- boxes arguments unnecessarily. In this situation, special variants
    -- of monadic @>>=@ can be helpful. If @C#@, @I#@, etc. never
    -- get used in your original source code, GHC will not introduce them.
  , bindFromCharToLifted
  , bindFromLiftedToIntPair
  , bindFromLiftedToInt
  , bindFromIntToIntPair
  , bindFromCharToIntPair
  , bindFromMaybeCharToIntPair
  , bindFromMaybeCharToLifted

    -- * Specialized Pure
  , pureIntPair

    -- * Specialized Fail
  , failIntPair
  ) where

import Prelude hiding (any, fail, length, replicate, take, takeWhile)

import Data.Bytes.Parser.Internal (Parser (..), Result#, ST#, boxBytes, fail, unboxBytes, uneffectful, uneffectful#, uneffectfulInt#)
import Data.Bytes.Parser.Types (Result (Failure, Success), Slice (Slice))
import Data.Bytes.Parser.Unsafe (cursor, expose, unconsume)
import Data.Bytes.Types (Bytes (..), BytesN (BytesN))
import Data.Primitive (ByteArray (..))
import Data.Primitive.Contiguous (Contiguous, Element)
import Foreign.C.String (CString)
import GHC.Exts (Char#, Int (I#), Int#, Word#, runRW#, (+#), (-#), (>=#))
import GHC.ST (ST (..))
import GHC.Word (Word32 (W32#), Word8)

import qualified Arithmetic.Nat as Nat
import qualified Arithmetic.Types as Arithmetic
import qualified Data.Bytes as B
import qualified Data.Bytes.Parser.Internal as Internal
import qualified Data.Primitive as PM
import qualified Data.Primitive.Contiguous as C
import qualified GHC.Exts as Exts

{- | Parse a byte sequence. This can succeed even if the
entire slice was not consumed by the parser.
-}
parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
{-# INLINE parseBytes #-}
parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
parseBytes forall s. Parser e s a
p !Bytes
b = (forall s. ST# s (Result# e a)) -> Result e a
forall e x. (forall s. ST# s (Result# e x)) -> Result e x
runResultST ST# s (Result# e a)
forall s. ST# s (Result# e a)
action
 where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

{- | Variant of 'parseBytesEither' that discards the error message on failure.
Just like 'parseBytesEither', this does not impose any checks on the length
of the remaining input.
-}
parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a
{-# INLINE parseBytesMaybe #-}
parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a
parseBytesMaybe forall s. Parser e s a
p !Bytes
b = (forall s. ST# s (Result# e a)) -> Maybe a
forall e x. (forall s. ST# s (Result# e x)) -> Maybe x
runMaybeST ST# s (Result# e a)
forall s. ST# s (Result# e a)
action
 where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

{- | Variant of 'parseBytes' that discards the new offset and the
remaining length. This does not, however, require the remaining
length to be zero. Use 'endOfInput' to accomplish that.
-}
parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a
{-# INLINE parseBytesEither #-}
parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a
parseBytesEither forall s. Parser e s a
p !Bytes
b = (forall s. ST# s (Result# e a)) -> Either e a
forall e x. (forall s. ST# s (Result# e x)) -> Either e x
runEitherST ST# s (Result# e a)
forall s. ST# s (Result# e a)
action
 where
  action :: forall s. ST# s (Result# e a)
  action :: forall s. ST# s (Result# e a)
action State# s
s0 = case forall s. Parser e s a
p @s of
    Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0

-- Similar to runResultST
runMaybeST :: (forall s. ST# s (Result# e x)) -> Maybe x
{-# INLINE runMaybeST #-}
runMaybeST :: forall e x. (forall s. ST# s (Result# e x)) -> Maybe x
runMaybeST forall s. ST# s (Result# e x)
f = case ((State# RealWorld -> Result# e x) -> Result# e x
forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case ST# RealWorld (Result# e x)
forall s. ST# s (Result# e x)
f State# RealWorld
s0 of (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r)) of
  (# e
_ | #) -> Maybe x
forall a. Maybe a
Nothing
  (# | (# x
x, Int#
_, Int#
_ #) #) -> x -> Maybe x
forall a. a -> Maybe a
Just x
x

-- Similar to runResultST
runEitherST :: (forall s. ST# s (Result# e x)) -> Either e x
{-# INLINE runEitherST #-}
runEitherST :: forall e x. (forall s. ST# s (Result# e x)) -> Either e x
runEitherST forall s. ST# s (Result# e x)
f = case ((State# RealWorld -> Result# e x) -> Result# e x
forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case ST# RealWorld (Result# e x)
forall s. ST# s (Result# e x)
f State# RealWorld
s0 of (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r)) of
  (# e
e | #) -> e -> Either e x
forall a b. a -> Either a b
Left e
e
  (# | (# x
x, Int#
_, Int#
_ #) #) -> x -> Either e x
forall a b. b -> Either a b
Right x
x

-- This is used internally to help reduce boxing when a parser
-- gets run. Due to the late inlining of runRW#, this variant
-- of runST still cause the result value to be boxed. However,
-- it avoids the additional boxing that the Success data
-- constructor would normally cause.
runResultST :: (forall s. ST# s (Result# e x)) -> Result e x
{-# INLINE runResultST #-}
runResultST :: forall e x. (forall s. ST# s (Result# e x)) -> Result e x
runResultST forall s. ST# s (Result# e x)
f = case ((State# RealWorld -> Result# e x) -> Result# e x
forall o. (State# RealWorld -> o) -> o
runRW# (\State# RealWorld
s0 -> case ST# RealWorld (Result# e x)
forall s. ST# s (Result# e x)
f State# RealWorld
s0 of (# State# RealWorld
_, Result# e x
r #) -> Result# e x
r)) of
  (# e
e | #) -> e -> Result e x
forall e a. e -> Result e a
Failure e
e
  (# | (# x
x, Int#
off, Int#
len #) #) -> Slice x -> Result e x
forall e a. Slice a -> Result e a
Success (Int -> Int -> x -> Slice x
forall a. Int -> Int -> a -> Slice a
Slice (Int# -> Int
I# Int#
off) (Int# -> Int
I# Int#
len) x
x)

-- | Variant of 'parseBytes' that accepts an unsliced 'ByteArray'.
parseByteArray :: (forall s. Parser e s a) -> ByteArray -> Result e a
{-# INLINE parseByteArray #-}
parseByteArray :: forall e a. (forall s. Parser e s a) -> ByteArray -> Result e a
parseByteArray forall s. Parser e s a
p ByteArray
b =
  (forall s. Parser e s a) -> Bytes -> Result e a
forall e a. (forall s. Parser e s a) -> Bytes -> Result e a
parseBytes Parser e s a
forall s. Parser e s a
p (ByteArray -> Int -> Int -> Bytes
Bytes ByteArray
b Int
0 (ByteArray -> Int
PM.sizeofByteArray ByteArray
b))

{- | Variant of 'parseBytes' that allows the parser to be run
as part of an existing effectful context.
-}
parseBytesEffectfully :: Parser e s a -> Bytes -> ST s (Result e a)
{-# INLINE parseBytesEffectfully #-}
parseBytesEffectfully :: forall e s a. Parser e s a -> Bytes -> ST s (Result e a)
parseBytesEffectfully (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) !Bytes
b =
  STRep s (Result e a) -> ST s (Result e a)
forall s a. STRep s a -> ST s a
ST
    ( \State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes Bytes
b) State# s
s0 of
        (# State# s
s1, Result# e a
r #) -> (# State# s
s1, Result# e a -> Result e a
forall e a. Result# e a -> Result e a
boxPublicResult Result# e a
r #)
    )

-- | Lift an effectful computation into a parser.
effect :: ST s a -> Parser e s a
{-# INLINE effect #-}
effect :: forall s a e. ST s a -> Parser e s a
effect (ST STRep s a
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#
_, Int#
off, Int#
len #) State# s
s0 -> case STRep s a
f State# s
s0 of
        (# State# s
s1, a
a #) -> (# State# s
s1, (# | (# a
a, Int#
off, Int#
len #) #) #)
    )

byteArray :: e -> ByteArray -> Parser e s ()
{-# INLINE byteArray #-}
byteArray :: forall e s. e -> ByteArray -> Parser e s ()
byteArray e
e !ByteArray
expected = e -> Bytes -> Parser e s ()
forall e s. e -> Bytes -> Parser e s ()
bytes e
e (ByteArray -> Bytes
B.fromByteArray ByteArray
expected)

-- | Consume input matching the byte sequence.
bytes :: e -> Bytes -> Parser e s ()
bytes :: forall e s. e -> Bytes -> Parser e s ()
bytes e
e !Bytes
expected =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e ()))
-> Parser e s ()
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \actual :: (# ByteArray#, Int#, Int# #)
actual@(# ByteArray#
_, Int#
off, Int#
len #) State# s
s ->
        let r :: Result# e ()
r =
              if Bytes -> Bytes -> Bool
B.isPrefixOf Bytes
expected ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
actual)
                then
                  let !(I# Int#
movement) = Bytes -> Int
length Bytes
expected
                   in (# | (# (), Int#
off Int# -> Int# -> Int#
+# Int#
movement, Int#
len Int# -> Int# -> Int#
-# Int#
movement #) #)
                else (# e
e | #)
         in (# State# s
s, Result# e ()
r #)
    )

{- FOURMOLU_DISABLE -}
-- | Consume input matching the @NUL@-terminated C String.
cstring :: e -> CString -> Parser e s ()
cstring :: forall e s. e -> CString -> Parser e s ()
cstring e
e (Exts.Ptr Addr#
ptr0) = ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e ()))
-> Parser e s ()
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
  ( \(# ByteArray#
arr, Int#
off0, Int#
len0 #) State# s
s ->
    let go :: Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go !Addr#
ptr !Int#
off !Int#
len = case
#if MIN_VERSION_base(4,16,0)
                 Word8# -> Word#
Exts.word8ToWord#
#endif
            (Addr# -> Int# -> Word8#
Exts.indexWord8OffAddr# Addr#
ptr Int#
0#) of
          Word#
0## -> (# State# s
s, (# | (# (), Int#
off, Int#
len #) #) #)
          Word#
c -> case Int#
len of
            Int#
0# -> (# State# s
s, (# e
e | #) #)
            Int#
_ -> case Word# -> Word# -> Int#
Exts.eqWord# Word#
c (
#if MIN_VERSION_base(4,16,0)
                 Word8# -> Word#
Exts.word8ToWord#
#endif
              (ByteArray# -> Int# -> Word8#
Exts.indexWord8Array# ByteArray#
arr Int#
off)) of
              Int#
1# -> Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go (Addr# -> Int# -> Addr#
Exts.plusAddr# Addr#
ptr Int#
1# ) (Int#
off Int# -> Int# -> Int#
+# Int#
1# ) (Int#
len Int# -> Int# -> Int#
-# Int#
1# )
              Int#
_ -> (# State# s
s, (# e
e | #) #)
     in Addr# -> Int# -> Int# -> (# State# s, Result# e () #)
go Addr#
ptr0 Int#
off0 Int#
len0
  )
{- FOURMOLU_ENABLE -}

infix 0 <?>

-- | Infix version of 'annotate'.
(<?>) :: Parser x s a -> e -> Parser e s a
<?> :: forall x s a e. Parser x s a -> e -> Parser e s a
(<?>) = Parser x s a -> e -> Parser e s a
forall x s a e. Parser x s a -> e -> Parser e s a
annotate

{- | Annotate a parser. If the parser fails, the error will
  be returned.
-}
annotate :: Parser x s a -> e -> Parser e s a
annotate :: forall x s a e. Parser x s a -> e -> Parser e s a
annotate Parser x s a
p e
e = Parser x s a
p Parser x s a -> Parser e s a -> Parser e s a
forall x s a e. Parser x s a -> Parser e s a -> Parser e s a
`orElse` e -> Parser e s a
forall e s a. e -> Parser e s a
fail e
e

{- | Consumes and returns the next byte in the input.
Fails if no characters are left.
-}
any :: e -> Parser e s Word8
{-# INLINE any #-}
any :: forall e s. e -> Parser e s Word8
any e
e = (Bytes -> Result e Word8) -> Parser e s Word8
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Word8) -> Parser e s Word8)
-> (Bytes -> Result e Word8) -> Parser e s Word8
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then
      let w :: Word8
w = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
       in Word8 -> Int -> Int -> Result e Word8
forall e a. a -> Int -> Int -> Result e a
Internal.Success Word8
w (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
    else e -> Result e Word8
forall e a. e -> Result e a
Internal.Failure e
e

{- | Match any byte, to perform lookahead. Returns 'Nothing' if
  end of input has been reached. Does not consume any input.

  /Note/: Because this parser does not fail, do not use it
  with combinators such as 'many', because such as 'many',
  because such parsers loop until a failure occurs. Careless
  use will thus result in an infinite loop.
-}
peek :: Parser e s (Maybe Word8)
{-# INLINE peek #-}
peek :: forall e s. Parser e s (Maybe Word8)
peek = (Bytes -> Result e (Maybe Word8)) -> Parser e s (Maybe Word8)
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e (Maybe Word8)) -> Parser e s (Maybe Word8))
-> (Bytes -> Result e (Maybe Word8)) -> Parser e s (Maybe Word8)
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  let v :: Maybe Word8
v =
        if Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
          then Word8 -> Maybe Word8
forall a. a -> Maybe a
Just (Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
0)
          else Maybe Word8
forall a. Maybe a
Nothing
   in Maybe Word8 -> Int -> Int -> Result e (Maybe Word8)
forall e a. a -> Int -> Int -> Result e a
Internal.Success Maybe Word8
v (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)

{- | Match any byte, to perform lookahead. Does not consume any
  input, but will fail if end of input has been reached.
-}
peek' :: e -> Parser e s Word8
{-# INLINE peek' #-}
peek' :: forall e s. e -> Parser e s Word8
peek' e
e = (Bytes -> Result e Word8) -> Parser e s Word8
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Word8) -> Parser e s Word8)
-> (Bytes -> Result e Word8) -> Parser e s Word8
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then Word8 -> Int -> Int -> Result e Word8
forall e a. a -> Int -> Int -> Result e a
Internal.Success (Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
0) (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)
    else e -> Result e Word8
forall e a. e -> Result e a
Internal.Failure e
e

{- | 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 the initial state
  if the predicate returns 'Nothing' on the first byte of input.

  /Note/: Because this parser does not fail, do not use it with
  combinators such a 'many', because such parsers loop until a
  failure occurs. Careless use will thus result in an infinite loop.
-}
scan :: state -> (state -> Word8 -> Maybe state) -> Parser e s state
{-# INLINE scan #-}
scan :: forall state e s.
state -> (state -> Word8 -> Maybe state) -> Parser e s state
scan state
s0 state -> Word8 -> Maybe state
t = do
  let go :: state -> Parser e s state
go state
s = do
        Maybe Word8
mw <- Parser e s (Maybe Word8)
forall e s. Parser e s (Maybe Word8)
peek
        case Maybe Word8
mw of
          Maybe Word8
Nothing -> state -> Parser e s state
forall a. a -> Parser e s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure state
s
          Just Word8
w -> case state -> Word8 -> Maybe state
t state
s Word8
w of
            Just state
s' -> state -> Parser e s state
go state
s'
            Maybe state
Nothing -> state -> Parser e s state
forall a. a -> Parser e s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure state
s
  state -> Parser e s state
forall {e} {s}. state -> Parser e s state
go state
s0

-- Interpret the next byte as an ASCII-encoded character.
-- Does not check to see if any characters are left. This
-- is not exported.
anyUnsafe :: Parser e s Word8
{-# INLINE anyUnsafe #-}
anyUnsafe :: forall e s. Parser e s Word8
anyUnsafe = (Bytes -> Result e Word8) -> Parser e s Word8
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Word8) -> Parser e s Word8)
-> (Bytes -> Result e Word8) -> Parser e s Word8
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  let w :: Word8
w = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
chunk) (Bytes -> Int
offset Bytes
chunk) :: Word8
   in Word8 -> Int -> Int -> Result e Word8
forall e a. a -> Int -> Int -> Result e a
Internal.Success Word8
w (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

{- | Take while the predicate is matched. This is always inlined. This
always succeeds.
-}
takeWhile :: (Word8 -> Bool) -> Parser e s Bytes
{-# INLINE takeWhile #-}
takeWhile :: forall e s. (Word8 -> Bool) -> Parser e s Bytes
takeWhile Word8 -> Bool
f = (Bytes -> Result e Bytes) -> Parser e s Bytes
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bytes) -> Parser e s Bytes)
-> (Bytes -> Result e Bytes) -> Parser e s Bytes
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk -> case (Word8 -> Bool) -> Bytes -> Bytes
B.takeWhile Word8 -> Bool
f Bytes
chunk of
  Bytes
bs -> Bytes -> Int -> Int -> Result e Bytes
forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
bs (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Bytes -> Int
length Bytes
bs) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Bytes -> Int
length Bytes
bs)

{- | Take bytes until the specified byte is encountered. Consumes
the matched byte as well. Fails if the byte is not present.
Visually, the cursor advancement and resulting @Bytes@ for
@takeTrailedBy 0x19@ look like this:

>  0x10 0x13 0x08 0x15 0x19 0x23 0x17 | input
> |---->---->---->---->----|          | cursor
> {\----*----*----*----\}               | result bytes
-}
takeTrailedBy :: e -> Word8 -> Parser e s Bytes
takeTrailedBy :: forall e s. e -> Word8 -> Parser e s Bytes
takeTrailedBy e
e !Word8
w = do
  !Int
start <- Parser e s Int
forall e s. Parser e s Int
cursor
  e -> Word8 -> Parser e s ()
forall e s. e -> Word8 -> Parser e s ()
skipTrailedBy e
e Word8
w
  !Int
end <- Parser e s Int
forall e s. Parser e s Int
cursor
  !ByteArray
arr <- Parser e s ByteArray
forall e s. Parser e s ByteArray
expose
  Bytes -> Parser e s Bytes
forall a. a -> Parser e s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteArray -> Int -> Int -> Bytes
Bytes ByteArray
arr Int
start (Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)))

{- | Skip all characters until the character from the is encountered
and then consume the matching byte as well.
-}
skipTrailedBy :: e -> Word8 -> Parser e s ()
{-# INLINE skipTrailedBy #-}
skipTrailedBy :: forall e s. e -> Word8 -> Parser e s ()
skipTrailedBy e
e !Word8
w = (Bytes -> Result# e ()) -> Parser e s ()
forall e a s. (Bytes -> Result# e a) -> Parser e s a
uneffectful# (\Bytes
c -> e -> Word8 -> Bytes -> Result# e ()
forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e Word8
w Bytes
c)

skipUntilConsumeByteLoop ::
  e -> -- Error message
  Word8 -> -- byte to match
  Bytes -> -- Chunk
  Result# e ()
skipUntilConsumeByteLoop :: forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e !Word8
w !Bytes
c =
  if Bytes -> Int
length Bytes
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then
      if ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= (Word8
w :: Word8)
        then e -> Word8 -> Bytes -> (# e | (# (), Int#, Int# #) #)
forall e. e -> Word8 -> Bytes -> Result# e ()
skipUntilConsumeByteLoop e
e Word8
w (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
        else (# | (# (), Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
    else (# e
e | #)

{- | Skip all bytes until either of the bytes in encountered. Then,
consume the matched byte. @True@ indicates that the first argument
byte was encountered. @False@ indicates that the second argument
byte was encountered.
-}
skipTrailedBy2 ::
  -- | Error message
  e ->
  -- | First trailer, @False@ indicates that this was encountered
  Word8 ->
  -- | Second trailer, @True@ indicates that this was encountered
  Word8 ->
  Parser e s Bool
{-# INLINE skipTrailedBy2 #-}
skipTrailedBy2 :: forall e s. e -> Word8 -> Word8 -> Parser e s Bool
skipTrailedBy2 e
e !Word8
wa !Word8
wb = Parser e s Int# -> Parser e s Bool
forall e s. Parser e s Int# -> Parser e s Bool
boxBool (e -> Word8 -> Word8 -> Parser e s Int#
forall e s. e -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy2# e
e Word8
wa Word8
wb)

skipTrailedBy2# ::
  -- | Error message
  e ->
  -- | First trailer, 0 indicates that this was encountered
  Word8 ->
  -- | Second trailer, 1 indicates that this was encountered
  Word8 ->
  Parser e s Int#
{-# INLINE skipTrailedBy2# #-}
skipTrailedBy2# :: forall e s. e -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy2# e
e !Word8
wa !Word8
wb =
  (Bytes -> Result# e Int#) -> Parser e s Int#
forall e s. (Bytes -> Result# e Int#) -> Parser e s Int#
uneffectfulInt# (\Bytes
c -> e -> Word8 -> Word8 -> Bytes -> Result# e Int#
forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e Word8
wa Word8
wb Bytes
c)

skipTrailedBy3# ::
  -- | Error message
  e ->
  -- | First trailer, 0 indicates that this was encountered
  Word8 ->
  -- | Second trailer, 1 indicates that this was encountered
  Word8 ->
  -- | Third trailer, 2 indicates that this was encountered
  Word8 ->
  Parser e s Int#
{-# INLINE skipTrailedBy3# #-}
skipTrailedBy3# :: forall e s. e -> Word8 -> Word8 -> Word8 -> Parser e s Int#
skipTrailedBy3# e
e !Word8
wa !Word8
wb !Word8
wc =
  (Bytes -> Result# e Int#) -> Parser e s Int#
forall e s. (Bytes -> Result# e Int#) -> Parser e s Int#
uneffectfulInt# (\Bytes
c -> e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e Word8
wa Word8
wb Word8
wc Bytes
c)

skipUntilConsumeByteEitherLoop ::
  e -> -- Error message
  Word8 -> -- first trailer
  Word8 -> -- second trailer
  Bytes -> -- Chunk
  Result# e Int#
skipUntilConsumeByteEitherLoop :: forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e !Word8
wa !Word8
wb !Bytes
c =
  if Bytes -> Int
length Bytes
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then
      let byte :: Word8
byte = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c)
       in if
            | Word8
byte Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
wa -> (# | (# Int#
0#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
            | Word8
byte Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
wb -> (# | (# Int#
1#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
            | Bool
otherwise -> e -> Word8 -> Word8 -> Bytes -> Result# e Int#
forall e. e -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByteEitherLoop e
e Word8
wa Word8
wb (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
    else (# e
e | #)

skipUntilConsumeByte3Loop ::
  e -> -- Error message
  Word8 -> -- first trailer
  Word8 -> -- second trailer
  Word8 -> -- third trailer
  Bytes -> -- Chunk
  Result# e Int#
skipUntilConsumeByte3Loop :: forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e !Word8
wa !Word8
wb !Word8
wc !Bytes
c =
  if Bytes -> Int
length Bytes
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then
      let byte :: Word8
byte = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray (Bytes -> ByteArray
array Bytes
c) (Bytes -> Int
offset Bytes
c)
       in if
            | Word8
byte Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
wa -> (# | (# Int#
0#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
            | Word8
byte Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
wb -> (# | (# Int#
1#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
            | Word8
byte Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
wc -> (# | (# Int#
2#, Int -> Int#
unI (Bytes -> Int
offset Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Int -> Int#
unI (Bytes -> Int
length Bytes
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) #) #)
            | Bool
otherwise -> e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
forall e. e -> Word8 -> Word8 -> Word8 -> Bytes -> Result# e Int#
skipUntilConsumeByte3Loop e
e Word8
wa Word8
wb Word8
wc (Int -> Bytes -> Bytes
B.unsafeDrop Int
1 Bytes
c)
    else (# e
e | #)

{- | Take the given number of bytes. Fails if there is not enough
  remaining input.
-}
take :: e -> Int -> Parser e s Bytes
{-# INLINE take #-}
take :: forall e s. e -> Int -> Parser e s Bytes
take e
e Int
n = (Bytes -> Result e Bytes) -> Parser e s Bytes
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bytes) -> Parser e s Bytes)
-> (Bytes -> Result e Bytes) -> Parser e s Bytes
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Bytes -> Int
B.length Bytes
chunk
    then case Int -> Bytes -> Bytes
B.unsafeTake Int
n Bytes
chunk of
      Bytes
bs -> Bytes -> Int -> Int -> Result e Bytes
forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
bs (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
    else e -> Result e Bytes
forall e a. e -> Result e a
Internal.Failure e
e

-- | Variant of 'take' that tracks the length of the result in the result type.
takeN :: e -> Arithmetic.Nat n -> Parser e s (BytesN n)
takeN :: forall e (n :: Nat) s. e -> Nat n -> Parser e s (BytesN n)
takeN e
e Nat n
n0 = (Bytes -> Result e (BytesN n)) -> Parser e s (BytesN n)
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e (BytesN n)) -> Parser e s (BytesN n))
-> (Bytes -> Result e (BytesN n)) -> Parser e s (BytesN n)
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Bytes -> Int
B.length Bytes
chunk
    then case Int -> Bytes -> Bytes
B.unsafeTake Int
n Bytes
chunk of
      Bytes ByteArray
theChunk Int
theOff Int
_ -> BytesN n -> Int -> Int -> Result e (BytesN n)
forall e a. a -> Int -> Int -> Result e a
Internal.Success (ByteArray -> Int -> BytesN n
forall (n :: Nat). ByteArray -> Int -> BytesN n
BytesN ByteArray
theChunk Int
theOff) (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
    else e -> Result e (BytesN n)
forall e a. e -> Result e a
Internal.Failure e
e
 where
  !n :: Int
n = Nat n -> Int
forall (n :: Nat). Nat n -> Int
Nat.demote Nat n
n0

{- | Take at most the given number of bytes. This is greedy. It will
  consume as many bytes as there are available until it has consumed
  @n@ bytes. This never fails.
-}
takeUpTo :: Int -> Parser e s Bytes
{-# INLINE takeUpTo #-}
takeUpTo :: forall e s. Int -> Parser e s Bytes
takeUpTo Int
n = (Bytes -> Result e Bytes) -> Parser e s Bytes
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bytes) -> Parser e s Bytes)
-> (Bytes -> Result e Bytes) -> Parser e s Bytes
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  let m :: Int
m = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n (Bytes -> Int
B.length Bytes
chunk)
   in case Int -> Bytes -> Bytes
B.unsafeTake Int
m Bytes
chunk of
        Bytes
bs -> Bytes -> Int -> Int -> Result e Bytes
forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
bs (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
m) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
m)

-- | Consume all remaining bytes in the input.
remaining :: Parser e s Bytes
{-# INLINE remaining #-}
remaining :: forall e s. Parser e s Bytes
remaining = (Bytes -> Result e Bytes) -> Parser e s Bytes
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bytes) -> Parser e s Bytes)
-> (Bytes -> Result e Bytes) -> Parser e s Bytes
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  Bytes -> Int -> Int -> Result e Bytes
forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
chunk (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Bytes -> Int
length Bytes
chunk) Int
0

-- | Return all remaining bytes in the input without consuming them.
peekRemaining :: Parser e s Bytes
{-# INLINE peekRemaining #-}
peekRemaining :: forall e s. Parser e s Bytes
peekRemaining = (Bytes -> Result e Bytes) -> Parser e s Bytes
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bytes) -> Parser e s Bytes)
-> (Bytes -> Result e Bytes) -> Parser e s Bytes
forall a b. (a -> b) -> a -> b
$ \b :: Bytes
b@(Bytes ByteArray
_ Int
off Int
len) ->
  Bytes -> Int -> Int -> Result e Bytes
forall e a. a -> Int -> Int -> Result e a
Internal.Success Bytes
b Int
off Int
len

-- | Skip while the predicate is matched. This is always inlined.
skipWhile :: (Word8 -> Bool) -> Parser e s ()
{-# INLINE skipWhile #-}
skipWhile :: forall e s. (Word8 -> Bool) -> Parser e s ()
skipWhile Word8 -> Bool
f = Parser e s ()
forall {e} {s}. Parser e s ()
go
 where
  go :: Parser e s ()
go =
    Parser e s Bool
forall e s. Parser e s Bool
isEndOfInput Parser e s Bool -> (Bool -> Parser e s ()) -> Parser e s ()
forall a b. Parser e s a -> (a -> Parser e s b) -> Parser e s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Bool
True -> () -> Parser e s ()
forall a. a -> Parser e s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      Bool
False -> do
        Word8
w <- Parser e s Word8
forall e s. Parser e s Word8
anyUnsafe
        if Word8 -> Bool
f Word8
w
          then Parser e s ()
go
          else Int -> Parser e s ()
forall e s. Int -> Parser e s ()
unconsume Int
1

{- | The parser @satisfy p@ succeeds for any byte for which the
  predicate @p@ returns 'True'. Returns the byte that is
  actually parsed.
-}
satisfy :: e -> (Word8 -> Bool) -> Parser e s Word8
satisfy :: forall e s. e -> (Word8 -> Bool) -> Parser e s Word8
satisfy e
e Word8 -> Bool
p = e -> (Word8 -> Word8) -> (Word8 -> Bool) -> Parser e s Word8
forall e a s. e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
satisfyWith e
e Word8 -> Word8
forall a. a -> a
id Word8 -> Bool
p
{-# INLINE satisfy #-}

{- | 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 :: e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
{-# INLINE satisfyWith #-}
satisfyWith :: forall e a s. e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a
satisfyWith e
e Word8 -> a
f a -> Bool
p = (Bytes -> Result e a) -> Parser e s a
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e a) -> Parser e s a)
-> (Bytes -> Result e a) -> Parser e s a
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
    then case Bytes -> Int -> Word8
B.unsafeIndex Bytes
chunk Int
0 of
      Word8
w ->
        let v :: a
v = Word8 -> a
f Word8
w
         in if a -> Bool
p a
v
              then a -> Int -> Int -> Result e a
forall e a. a -> Int -> Int -> Result e a
Internal.Success a
v (Bytes -> Int
offset Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Bytes -> Int
length Bytes
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
              else e -> Result e a
forall e a. e -> Result e a
Internal.Failure e
e
    else e -> Result e a
forall e a. e -> Result e a
Internal.Failure e
e

-- | Fails if there is still more input remaining.
endOfInput :: e -> Parser e s ()
{-# INLINE endOfInput #-}
endOfInput :: forall e s. e -> Parser e s ()
endOfInput e
e = (Bytes -> Result e ()) -> Parser e s ()
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e ()) -> Parser e s ())
-> (Bytes -> Result e ()) -> Parser e s ()
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  if Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
    then () -> Int -> Int -> Result e ()
forall e a. a -> Int -> Int -> Result e a
Internal.Success () (Bytes -> Int
offset Bytes
chunk) Int
0
    else e -> Result e ()
forall e a. e -> Result e a
Internal.Failure e
e

{- | Returns true if there are no more bytes in the input. Returns
false otherwise. Always succeeds.
-}
isEndOfInput :: Parser e s Bool
{-# INLINE isEndOfInput #-}
isEndOfInput :: forall e s. Parser e s Bool
isEndOfInput = (Bytes -> Result e Bool) -> Parser e s Bool
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e Bool) -> Parser e s Bool)
-> (Bytes -> Result e Bool) -> Parser e s Bool
forall a b. (a -> b) -> a -> b
$ \Bytes
chunk ->
  Bool -> Int -> Int -> Result e Bool
forall e a. a -> Int -> Int -> Result e a
Internal.Success (Bytes -> Int
length Bytes
chunk Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Bytes -> Int
offset Bytes
chunk) (Bytes -> Int
length Bytes
chunk)

boxPublicResult :: Result# e a -> Result e a
{-# INLINE boxPublicResult #-}
boxPublicResult :: forall e a. Result# e a -> Result e a
boxPublicResult (# | (# a
a, Int#
b, Int#
c #) #) = Slice a -> Result e a
forall e a. Slice a -> Result e a
Success (Int -> Int -> a -> Slice a
forall a. Int -> Int -> a -> Slice a
Slice (Int# -> Int
I# Int#
b) (Int# -> Int
I# Int#
c) a
a)
boxPublicResult (# e
e | #) = e -> Result e a
forall e a. e -> Result e a
Failure e
e

{- FOURMOLU_DISABLE -}
-- | Convert a 'Word32' parser to a 'Word#' parser.
unboxWord32 :: Parser e s Word32 -> Parser e s Word#
{-# inline unboxWord32 #-}
unboxWord32 :: forall e s. Parser e s Word32 -> Parser e s Word#
unboxWord32 (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word32)
f) = ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word#))
-> Parser e s Word#
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word32)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Word32
r #) -> case Result# e Word32
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# W32# Word32#
a, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (#
#if MIN_VERSION_base(4,16,0)
        Word32# -> Word#
Exts.word32ToWord#
#endif
        Word32#
a, Int#
b, Int#
c #) #) #)
  )
{- FOURMOLU_ENABLE -}

-- | Convert a @(Int,Int)@ parser to a @(# Int#, Int# #)@ parser.
unboxIntPair :: Parser e s (Int, Int) -> Parser e s (# Int#, Int# #)
{-# INLINE unboxIntPair #-}
unboxIntPair :: forall e s. Parser e s (Int, Int) -> Parser e s (# Int#, Int# #)
unboxIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, Int))
f) =
  ((# ByteArray#, Int#, Int# #)
 -> ST# s (Result# e (# Int#, Int# #)))
-> Parser e s (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, Int))
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e (Int, Int)
r #) -> case Result# e (Int, Int)
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# (I# Int#
y, I# Int#
z), Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# (# Int#
y, Int#
z #), Int#
b, Int#
c #) #) #)
    )

{- FOURMOLU_DISABLE -}
-- | Convert a 'Word#' parser to a 'Word32' parser. Precondition:
-- the argument parser only returns words less than 4294967296.
boxWord32 :: Parser e s Word# -> Parser e s Word32
{-# inline boxWord32 #-}
boxWord32 :: forall e s. Parser e s Word# -> Parser e s Word32
boxWord32 (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word#)
f) = ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word32))
-> Parser e s Word32
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
  (\(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Word#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
    (# State# s
s1, Result# e Word#
r #) -> case Result# e Word#
r of
      (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
      (# | (# Word#
a, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# Word32# -> Word32
W32# (
#if MIN_VERSION_base(4,16,0)
        Word# -> Word32#
Exts.wordToWord32#
#endif
        Word#
a), Int#
b, Int#
c #) #) #)
  )
{- FOURMOLU_ENABLE -}

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxInt :: Parser e s Int# -> Parser e s Int
{-# INLINE boxInt #-}
boxInt :: forall e s. Parser e s Int# -> Parser e s Int
boxInt (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int))
-> Parser e s Int
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e Int#
r #) -> case Result# e Int#
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# Int#
y, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# Int# -> Int
I# Int#
y, Int#
b, Int#
c #) #) #)
    )

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxBool :: Parser e s Int# -> Parser e s Bool
{-# INLINE boxBool #-}
boxBool :: forall e s. Parser e s Int# -> Parser e s Bool
boxBool (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Bool))
-> Parser e s Bool
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e Int#
r #) -> case Result# e Int#
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# Int#
y, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# case Int#
y of Int#
1# -> Bool
True; Int#
_ -> Bool
False, Int#
b, Int#
c #) #) #)
    )

-- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser.
boxIntPair :: Parser e s (# Int#, Int# #) -> Parser e s (Int, Int)
{-# INLINE boxIntPair #-}
boxIntPair :: forall e s. Parser e s (# Int#, Int# #) -> Parser e s (Int, Int)
boxIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (# Int#, Int# #))
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, Int)))
-> Parser e s (Int, Int)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e (# Int#, Int# #))
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e (# Int#, Int# #)
r #) -> case Result# e (# Int#, Int# #)
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# (# Int#
y, Int#
z #), Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# (Int# -> Int
I# Int#
y, Int# -> Int
I# Int#
z), Int#
b, Int#
c #) #) #)
    )

{- | There is a law-abiding instance of 'Alternative' for 'Parser'.
However, it is not terribly useful since error messages seldom
have a 'Monoid' instance. This function is a variant of @\<|\>@
that is right-biased in its treatment of error messages.
Consequently, @orElse@ lacks an identity.
See <https://github.com/bos/attoparsec/issues/122 attoparsec issue #122>
for more discussion of this topic.
-}
infixl 3 `orElse`

orElse :: Parser x s a -> Parser e s a -> Parser e s a
{-# INLINE orElse #-}
orElse :: forall x s a e. Parser x s a -> Parser e s a -> Parser e s a
orElse (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# x a)
f) (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# x a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# x a
r0 #) -> case Result# x a
r0 of
          (# x
_ | #) -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g (# ByteArray#, Int#, Int# #)
x State# s
s1
          (# | (# a, Int#, Int# #)
r #) -> (# State# s
s1, (# | (# a, Int#, Int# #)
r #) #)
    )

-- | Effectfully adjusts the error message if an error occurs.
mapErrorEffectfully :: (e1 -> ST s e2) -> Parser e1 s a -> Parser e2 s a
{-# INLINE mapErrorEffectfully #-}
mapErrorEffectfully :: forall e1 s e2 a. (e1 -> ST s e2) -> Parser e1 s a -> Parser e2 s a
mapErrorEffectfully e1 -> ST s e2
f (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e1 a)
g) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e2 a))
-> Parser e2 s a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e1 a)
g (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e1 a
r0 #) -> case Result# e1 a
r0 of
          (# e1
e | #) -> case e1 -> ST s e2
f e1
e of
            ST STRep s e2
h -> case STRep s e2
h State# s
s1 of
              (# State# s
s2, e2
e' #) -> (# State# s
s2, (# e2
e' | #) #)
          (# | (# a, Int#, Int# #)
r #) -> (# State# s
s1, (# | (# a, Int#, Int# #)
r #) #)
    )

bindFromCharToLifted :: Parser s e Char# -> (Char# -> Parser s e a) -> Parser s e a
{-# INLINE bindFromCharToLifted #-}
bindFromCharToLifted :: forall s e a.
Parser s e Char# -> (Char# -> Parser s e a) -> Parser s e a
bindFromCharToLifted (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f) Char# -> Parser s e a
g =
  ((# ByteArray#, Int#, Int# #) -> ST# e (Result# s a))
-> Parser s e a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s Char#
r0 #) -> case Result# s Char#
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# Char#
y, Int#
b, Int#
c #) #) ->
            Parser s e a -> (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Char# -> Parser s e a
g Char#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromCharToIntPair :: Parser s e Char# -> (Char# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# INLINE bindFromCharToIntPair #-}
bindFromCharToIntPair :: forall s e.
Parser s e Char#
-> (Char# -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromCharToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f) Char# -> Parser s e (# Int#, Int# #)
g =
  ((# ByteArray#, Int#, Int# #)
 -> ST# e (Result# s (# Int#, Int# #)))
-> Parser s e (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Char#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s Char#
r0 #) -> case Result# s Char#
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# Char#
y, Int#
b, Int#
c #) #) ->
            Parser s e (# Int#, Int# #)
-> (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# Int#, Int# #))
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Char# -> Parser s e (# Int#, Int# #)
g Char#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromLiftedToInt :: Parser s e a -> (a -> Parser s e Int#) -> Parser s e Int#
{-# INLINE bindFromLiftedToInt #-}
bindFromLiftedToInt :: forall s e a.
Parser s e a -> (a -> Parser s e Int#) -> Parser s e Int#
bindFromLiftedToInt (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f) a -> Parser s e Int#
g =
  ((# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#))
-> Parser s e Int#
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s a
r0 #) -> case Result# s a
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# a
y, Int#
b, Int#
c #) #) ->
            Parser s e Int#
-> (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#)
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (a -> Parser s e Int#
g a
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromLiftedToIntPair :: Parser s e a -> (a -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# INLINE bindFromLiftedToIntPair #-}
bindFromLiftedToIntPair :: forall s e a.
Parser s e a
-> (a -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromLiftedToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f) a -> Parser s e (# Int#, Int# #)
g =
  ((# ByteArray#, Int#, Int# #)
 -> ST# e (Result# s (# Int#, Int# #)))
-> Parser s e (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s a
r0 #) -> case Result# s a
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# a
y, Int#
b, Int#
c #) #) ->
            Parser s e (# Int#, Int# #)
-> (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# Int#, Int# #))
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (a -> Parser s e (# Int#, Int# #)
g a
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromIntToIntPair :: Parser s e Int# -> (Int# -> Parser s e (# Int#, Int# #)) -> Parser s e (# Int#, Int# #)
{-# INLINE bindFromIntToIntPair #-}
bindFromIntToIntPair :: forall s e.
Parser s e Int#
-> (Int# -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromIntToIntPair (Parser (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#)
f) Int# -> Parser s e (# Int#, Int# #)
g =
  ((# ByteArray#, Int#, Int# #)
 -> ST# e (Result# s (# Int#, Int# #)))
-> Parser s e (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# e (Result# s Int#)
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s Int#
r0 #) -> case Result# s Int#
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# Int#
y, Int#
b, Int#
c #) #) ->
            Parser s e (# Int#, Int# #)
-> (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# Int#, Int# #))
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (Int# -> Parser s e (# Int#, Int# #)
g Int#
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromMaybeCharToIntPair ::
  Parser s e (# (# #) | Char# #) ->
  ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #)) ->
  Parser s e (# Int#, Int# #)
{-# INLINE bindFromMaybeCharToIntPair #-}
bindFromMaybeCharToIntPair :: forall s e.
Parser s e (# (# #) | Char# #)
-> ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #))
-> Parser s e (# Int#, Int# #)
bindFromMaybeCharToIntPair (Parser (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f) (# (# #) | Char# #) -> Parser s e (# Int#, Int# #)
g =
  ((# ByteArray#, Int#, Int# #)
 -> ST# e (Result# s (# Int#, Int# #)))
-> Parser s e (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s (# (# #) | Char# #)
r0 #) -> case Result# s (# (# #) | Char# #)
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# (# (# #) | Char# #)
y, Int#
b, Int#
c #) #) ->
            Parser s e (# Int#, Int# #)
-> (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# Int#, Int# #))
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser ((# (# #) | Char# #) -> Parser s e (# Int#, Int# #)
g (# (# #) | Char# #)
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

bindFromMaybeCharToLifted ::
  Parser s e (# (# #) | Char# #) ->
  ((# (# #) | Char# #) -> Parser s e a) ->
  Parser s e a
{-# INLINE bindFromMaybeCharToLifted #-}
bindFromMaybeCharToLifted :: forall s e a.
Parser s e (# (# #) | Char# #)
-> ((# (# #) | Char# #) -> Parser s e a) -> Parser s e a
bindFromMaybeCharToLifted (Parser (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f) (# (# #) | Char# #) -> Parser s e a
g =
  ((# ByteArray#, Int#, Int# #) -> ST# e (Result# s a))
-> Parser s e a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# e
s0 -> case (# ByteArray#, Int#, Int# #)
-> ST# e (Result# s (# (# #) | Char# #))
f (# ByteArray#, Int#, Int# #)
x State# e
s0 of
        (# State# e
s1, Result# s (# (# #) | Char# #)
r0 #) -> case Result# s (# (# #) | Char# #)
r0 of
          (# s
e | #) -> (# State# e
s1, (# s
e | #) #)
          (# | (# (# (# #) | Char# #)
y, Int#
b, Int#
c #) #) ->
            Parser s e a -> (# ByteArray#, Int#, Int# #) -> ST# e (Result# s a)
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser ((# (# #) | Char# #) -> Parser s e a
g (# (# #) | Char# #)
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# e
s1
    )

pureIntPair ::
  (# Int#, Int# #) ->
  Parser s e (# Int#, Int# #)
{-# INLINE pureIntPair #-}
pureIntPair :: forall s e. (# Int#, Int# #) -> Parser s e (# Int#, Int# #)
pureIntPair (# Int#, Int# #)
a =
  ((# ByteArray#, Int#, Int# #)
 -> ST# e (Result# s (# Int#, Int# #)))
-> Parser s e (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    (\(# ByteArray#
_, Int#
b, Int#
c #) State# e
s -> (# State# e
s, (# | (# (# Int#, Int# #)
a, Int#
b, Int#
c #) #) #))

failIntPair :: e -> Parser e s (# Int#, Int# #)
{-# INLINE failIntPair #-}
failIntPair :: forall e s. e -> Parser e s (# Int#, Int# #)
failIntPair e
e =
  ((# ByteArray#, Int#, Int# #)
 -> ST# s (Result# e (# Int#, Int# #)))
-> Parser e s (# Int#, Int# #)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    (\(# ByteArray#
_, Int#
_, Int#
_ #) State# s
s -> (# State# s
s, (# e
e | #) #))

{- | Augment a parser with the number of bytes that were consume while
it executed.
-}
measure :: Parser e s a -> Parser e s (Int, a)
{-# INLINE measure #-}
measure :: forall e s a. Parser e s a -> Parser e s (Int, a)
measure (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e (Int, a)))
-> Parser e s (Int, a)
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
_, Int#
pre, Int#
_ #) State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# a
y, Int#
post, Int#
c #) #) -> (# State# s
s1, (# | (# (Int# -> Int
I# (Int#
post Int# -> Int# -> Int#
-# Int#
pre), a
y), Int#
post, Int#
c #) #) #)
    )

{- | Run a parser and discard the result, returning instead the number
of bytes that the parser consumed.
-}
measure_ :: Parser e s a -> Parser e s Int
{-# INLINE measure_ #-}
measure_ :: forall e s a. Parser e s a -> Parser e s Int
measure_ Parser e s a
p = Parser e s Int# -> Parser e s Int
forall e s. Parser e s Int# -> Parser e s Int
boxInt (Parser e s a -> Parser e s Int#
forall e s a. Parser e s a -> Parser e s Int#
measure_# Parser e s a
p)

-- | Variant of 'measure_' with an unboxed result.
measure_# :: Parser e s a -> Parser e s Int#
{-# INLINE measure_# #-}
measure_# :: forall e s a. Parser e s a -> Parser e s Int#
measure_# (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#))
-> Parser e s Int#
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
_, Int#
pre, Int#
_ #) State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# a
_, Int#
post, Int#
c #) #) -> (# State# s
s1, (# | (# Int#
post Int# -> Int# -> Int#
-# Int#
pre, Int#
post, Int#
c #) #) #)
    )

{- | Run a parser in a delimited context, failing if the requested number
of bytes are not available or if the delimited parser does not
consume all input. This combinator can be understood as a composition
of 'take', 'effect', 'parseBytesEffectfully', and 'endOfInput'. It is
provided as a single combinator because for convenience and because it is
easy to make mistakes when manually assembling the aforementioned parsers.
The pattern of prefixing an encoding with its length is common.
This is discussed more in
<https://github.com/bos/attoparsec/issues/129 attoparsec issue #129>.

> delimit e1 e2 n remaining === take e1 n
-}
delimit ::
  -- | Error message when not enough bytes are present
  e ->
  -- | Error message when delimited parser does not consume all input
  e ->
  -- | Exact number of bytes delimited parser is expected to consume
  Int ->
  -- | Parser to execute in delimited context
  Parser e s a ->
  Parser e s a
{-# INLINE delimit #-}
delimit :: forall e s a. e -> e -> Int -> Parser e s a -> Parser e s a
delimit e
esz e
eleftovers (I# Int#
n) (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall a b c.
((# ByteArray#, Int#, Int# #) -> ST# b (Result# a c))
-> Parser a b c
Parser
    ( \(# ByteArray#
arr, Int#
off, Int#
len #) State# s
s0 -> case Int#
len Int# -> Int# -> Int#
>=# Int#
n of
        Int#
1# -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#
arr, Int#
off, Int#
n #) State# s
s0 of
          (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
            (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
            (# | (# a
a, Int#
newOff, Int#
leftovers #) #) -> case Int#
leftovers of
              Int#
0# -> (# State# s
s1, (# | (# a
a, Int#
newOff, Int#
len Int# -> Int# -> Int#
-# Int#
n #) #) #)
              Int#
_ -> (# State# s
s1, (# e
eleftovers | #) #)
        Int#
_ -> (# State# s
s0, (# e
esz | #) #)
    )

{- | Replicate a parser @n@ times, writing the results into
an array of length @n@. For @Array@ and @SmallArray@, this
is lazy in the elements, so be sure the they result of the
parser is evaluated appropriately to avoid unwanted thunks.
-}
replicate ::
  forall arr e s a.
  (Contiguous arr, Element arr a) =>
  -- | Number of times to run the parser
  Int ->
  -- | Parser
  Parser e s a ->
  Parser e s (arr a)
{-# INLINE replicate #-}
replicate :: forall (arr :: * -> *) e s a.
(Contiguous arr, Element arr a) =>
Int -> Parser e s a -> Parser e s (arr a)
replicate !Int
len Parser e s a
p = do
  Mutable arr s a
marr <- ST s (Mutable arr s a) -> Parser e s (Mutable arr s a)
forall s a e. ST s a -> Parser e s a
effect (Int -> ST s (Mutable arr (PrimState (ST s)) a)
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Int -> m (Mutable arr (PrimState m) b)
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Int -> m (Mutable arr (PrimState m) b)
C.new Int
len)
  let go :: Int -> Parser e s (arr a)
      go :: Int -> Parser e s (arr a)
go !Int
ix =
        if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
          then do
            a
a <- Parser e s a
p
            ST s () -> Parser e s ()
forall s a e. ST s a -> Parser e s a
effect (Mutable arr (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> b -> m ()
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> b -> m ()
C.write Mutable arr s a
Mutable arr (PrimState (ST s)) a
marr Int
ix a
a)
            Int -> Parser e s (arr a)
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
          else ST s (arr a) -> Parser e s (arr a)
forall s a e. ST s a -> Parser e s a
effect (Mutable arr (PrimState (ST s)) a -> ST s (arr a)
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> m (arr b)
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> m (arr b)
C.unsafeFreeze Mutable arr s a
Mutable arr (PrimState (ST s)) a
marr)
  Int -> Parser e s (arr a)
go Int
0

unI :: Int -> Int#
{-# INLINE unI #-}
unI :: Int -> Int#
unI (I# Int#
w) = Int#
w