    {-# LANGUAGE CPP #-}
    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Trustworthy #-}
    #endif
    -- |
    -- Module      :  Data.Attoparsec.ByteString
    -- Copyright   :  Bryan O'Sullivan 2007-2015
    -- License     :  BSD3
    --
    -- Maintainer  :  bos@serpentine.com
    -- Stability   :  experimental
    -- Portability :  unknown
    --
    -- Simple, efficient combinator parsing for 'B.ByteString' strings,
    -- loosely based on the Parsec library.

    module Data.Attoparsec.ByteString
        (
        -- * Differences from Parsec
        -- $parsec

        -- * Incremental input
        -- $incremental

        -- * Performance considerations
        -- $performance

        -- * Parser types
          I.Parser
        , Result
        , T.IResult(..)
        , I.compareResults

        -- * Running parsers
        , parse
        , feed
        , I.parseOnly
        , parseWith
        , parseTest

        -- ** Result conversion
        , maybeResult
        , eitherResult

        -- * Parsing individual bytes
        , I.word8
        , I.anyWord8
        , I.notWord8
        , I.satisfy
        , I.satisfyWith
        , I.skip

        -- ** Lookahead
        , I.peekWord8
        , I.peekWord8'

        -- ** Byte classes
        , I.inClass
        , I.notInClass

        -- * Efficient string handling
        , I.string
        , I.skipWhile
        , I.take
        , I.scan
        , I.runScanner
        , I.takeWhile
        , I.takeWhile1
        , I.takeWhileIncluding
        , I.takeTill
        , I.getChunk

        -- ** Consume all remaining input
        , I.takeByteString
        , I.takeLazyByteString

        -- * Combinators
        , try
        , (<?>)
        , choice
        , count
        , option
        , many'
        , many1
        , many1'
        , manyTill
        , manyTill'
        , sepBy
        , sepBy'
        , sepBy1
        , sepBy1'
        , skipMany
        , skipMany1
        , eitherP
        , I.match
        -- * State observation and manipulation functions
        , I.endOfInput
        , I.atEnd
        ) where

    import Data.Attoparsec.Combinator
    import Data.List (intercalate)
    import qualified Data.Attoparsec.ByteString.Internal as I
    import qualified Data.Attoparsec.Internal as I
    import qualified Data.ByteString as B
    import Data.Attoparsec.ByteString.Internal (Result, parse)
    import qualified Data.Attoparsec.Internal.Types as T

    -- $parsec
    --
    -- Compared to Parsec 3, attoparsec makes several tradeoffs.  It is
    -- not intended for, or ideal for, all possible uses.
    --
    -- * While attoparsec can consume input incrementally, Parsec cannot.
    --   Incremental input is a huge deal for efficient and secure network
    --   and system programming, since it gives much more control to users
    --   of the library over matters such as resource usage and the I/O
    --   model to use.
    --
    -- * Much of the performance advantage of attoparsec is gained via
    --   high-performance parsers such as 'I.takeWhile' and 'I.string'.
    --   If you use complicated combinators that return lists of bytes or
    --   characters, there is less performance difference between the two
    --   libraries.
    --
    -- * Unlike Parsec 3, attoparsec does not support being used as a
    --   monad transformer.
    --
    -- * attoparsec is specialised to deal only with strict 'B.ByteString'
    --   input.  Efficiency concerns rule out both lists and lazy
    --   bytestrings.  The usual use for lazy bytestrings would be to
    --   allow consumption of very large input without a large footprint.
    --   For this need, attoparsec's incremental input provides an
    --   excellent substitute, with much more control over when input
    --   takes place.  If you must use lazy bytestrings, see the
    --   "Data.Attoparsec.ByteString.Lazy" module, which feeds lazy chunks
    --   to a regular parser.
    --
    -- * Parsec parsers can produce more helpful error messages than
    --   attoparsec parsers.  This is a matter of focus: attoparsec avoids
    --   the extra book-keeping in favour of higher performance.

    -- $incremental
    --
    -- attoparsec supports incremental input, meaning that you can feed it
    -- a bytestring that represents only part of the expected total amount
    -- of data to parse. If your parser reaches the end of a fragment of
    -- input and could consume more input, it will suspend parsing and
    -- return a 'T.Partial' continuation.
    --
    -- Supplying the 'T.Partial' continuation with a bytestring will
    -- resume parsing at the point where it was suspended, with the
    -- bytestring you supplied used as new input at the end of the
    -- existing input. You must be prepared for the result of the resumed
    -- parse to be another 'T.Partial' continuation.
    --
    -- To indicate that you have no more input, supply the 'T.Partial'
    -- continuation with an empty bytestring.
    --
    -- Remember that some parsing combinators will not return a result
    -- until they reach the end of input.  They may thus cause 'T.Partial'
    -- results to be returned.
    --
    -- If you do not need support for incremental input, consider using
    -- the 'I.parseOnly' function to run your parser.  It will never
    -- prompt for more input.
    --
    -- /Note/: incremental input does /not/ imply that attoparsec will
    -- release portions of its internal state for garbage collection as it
    -- proceeds.  Its internal representation is equivalent to a single
    -- 'ByteString': if you feed incremental input to a parser, it will
    -- require memory proportional to the amount of input you supply.
    -- (This is necessary to support arbitrary backtracking.)

    -- $performance
    --
    -- If you write an attoparsec-based parser carefully, it can be
    -- realistic to expect it to perform similarly to a hand-rolled C
    -- parser (measuring megabytes parsed per second).
    --
    -- To actually achieve high performance, there are a few guidelines
    -- that it is useful to follow.
    --
    -- Use the 'B.ByteString'-oriented parsers whenever possible,
    -- e.g. 'I.takeWhile1' instead of 'many1' 'I.anyWord8'.  There is
    -- about a factor of 100 difference in performance between the two
    -- kinds of parser.
    --
    -- For very simple byte-testing predicates, write them by hand instead
    -- of using 'I.inClass' or 'I.notInClass'.  For instance, both of
    -- these predicates test for an end-of-line byte, but the first is
    -- much faster than the second:
    --
    -- >endOfLine_fast w = w == 13 || w == 10
    -- >endOfLine_slow   = inClass "\r\n"
    --
    -- Make active use of benchmarking and profiling tools to measure,
    -- find the problems with, and improve the performance of your parser.

    -- | Run a parser and print its result to standard output.
    parseTest :: (Show a) => I.Parser a -> B.ByteString -> IO ()
    parseTest :: forall a. Show a => Parser a -> ByteString -> IO ()
    parseTest Parser a
    p ByteString
    s = Result a -> IO ()
    forall a. Show a => a -> IO ()
    print (Parser a -> ByteString -> Result a
    forall a. Parser a -> ByteString -> Result a
    parse Parser a
    p ByteString
    s)

    -- | Run a parser with an initial input string, and a monadic action
    -- that can supply more input if needed.
    parseWith :: Monad m =>
                 (m B.ByteString)
              -- ^ An action that will be executed to provide the parser
              -- with more input, if necessary.  The action must return an
              -- 'B.empty' string when there is no more input available.
              -> I.Parser a
              -> B.ByteString
              -- ^ Initial input for the parser.
              -> m (Result a)
    parseWith :: forall (m :: * -> *) a.
    Monad m =>
    m ByteString -> Parser a -> ByteString -> m (Result a)
    parseWith m ByteString
    refill Parser a
    p ByteString
    s = IResult ByteString a -> m (IResult ByteString a)
    forall {r}. IResult ByteString r -> m (IResult ByteString r)
    step (IResult ByteString a -> m (IResult ByteString a))
    -> IResult ByteString a -> m (IResult ByteString a)
    forall a b. (a -> b) -> a -> b
    $ Parser a -> ByteString -> IResult ByteString a
    forall a. Parser a -> ByteString -> Result a
    parse Parser a
    p ByteString
    s
      where step :: IResult ByteString r -> m (IResult ByteString r)
    step (T.Partial ByteString -> IResult ByteString r
    k) = (IResult ByteString r -> m (IResult ByteString r)
    step (IResult ByteString r -> m (IResult ByteString r))
    -> (ByteString -> IResult ByteString r)
    -> ByteString
    -> m (IResult ByteString r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> IResult ByteString r
    k) (ByteString -> m (IResult ByteString r))
    -> m ByteString -> m (IResult ByteString r)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< m ByteString
    refill
            step IResult ByteString r
    r             = IResult ByteString r -> m (IResult ByteString r)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return IResult ByteString r
    r
    {-# INLINE parseWith #-}

    -- | Convert a 'Result' value to a 'Maybe' value. A 'T.Partial' result
    -- is treated as failure.
    maybeResult :: Result r -> Maybe r
    maybeResult :: forall r. Result r -> Maybe r
    maybeResult (T.Done ByteString
    _ r
    r) = r -> Maybe r
    forall a. a -> Maybe a
    Just r
    r
    maybeResult IResult ByteString r
    _            = Maybe r
    forall a. Maybe a
    Nothing

    -- | Convert a 'Result' value to an 'Either' value. A 'T.Partial'
    -- result is treated as failure.
    eitherResult :: Result r -> Either String r
    eitherResult :: forall r. Result r -> Either String r
    eitherResult (T.Done ByteString
    _ r
    r)        = r -> Either String r
    forall a b. b -> Either a b
    Right r
    r
    eitherResult (T.Fail ByteString
    _ [] String
    msg)   = String -> Either String r
    forall a b. a -> Either a b
    Left String
    msg
    eitherResult (T.Fail ByteString
    _ [String]
    ctxs String
    msg) = String -> Either String r
    forall a b. a -> Either a b
    Left (String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    " > " [String]
    ctxs String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ": " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    msg)
    eitherResult IResult ByteString r
    _                   = String -> Either String r
    forall a b. a -> Either a b
    Left String
    "Result: incomplete input"