module Data.Attoparsec.Run where

import Data.Attoparsec.Types

import Data.List (intercalate)
import Prelude (Either (..), Eq, Ord, Show, String, error, otherwise, null, (++))

data FinalResult i a = FinalResult
    i -- ^ Remaining unparsed input
    (Either ParseError a) -- ^ Either an error or a successfully parsed value
    deriving (FinalResult i a -> FinalResult i a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall i a.
(Eq i, Eq a) =>
FinalResult i a -> FinalResult i a -> Bool
/= :: FinalResult i a -> FinalResult i a -> Bool
$c/= :: forall i a.
(Eq i, Eq a) =>
FinalResult i a -> FinalResult i a -> Bool
== :: FinalResult i a -> FinalResult i a -> Bool
$c== :: forall i a.
(Eq i, Eq a) =>
FinalResult i a -> FinalResult i a -> Bool
Eq, FinalResult i a -> FinalResult i a -> Bool
FinalResult i a -> FinalResult i a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {i} {a}. (Ord i, Ord a) => Eq (FinalResult i a)
forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Bool
forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Ordering
forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> FinalResult i a
min :: FinalResult i a -> FinalResult i a -> FinalResult i a
$cmin :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> FinalResult i a
max :: FinalResult i a -> FinalResult i a -> FinalResult i a
$cmax :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> FinalResult i a
>= :: FinalResult i a -> FinalResult i a -> Bool
$c>= :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Bool
> :: FinalResult i a -> FinalResult i a -> Bool
$c> :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Bool
<= :: FinalResult i a -> FinalResult i a -> Bool
$c<= :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Bool
< :: FinalResult i a -> FinalResult i a -> Bool
$c< :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Bool
compare :: FinalResult i a -> FinalResult i a -> Ordering
$ccompare :: forall i a.
(Ord i, Ord a) =>
FinalResult i a -> FinalResult i a -> Ordering
Ord, Int -> FinalResult i a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall i a. (Show i, Show a) => Int -> FinalResult i a -> ShowS
forall i a. (Show i, Show a) => [FinalResult i a] -> ShowS
forall i a. (Show i, Show a) => FinalResult i a -> String
showList :: [FinalResult i a] -> ShowS
$cshowList :: forall i a. (Show i, Show a) => [FinalResult i a] -> ShowS
show :: FinalResult i a -> String
$cshow :: forall i a. (Show i, Show a) => FinalResult i a -> String
showsPrec :: Int -> FinalResult i a -> ShowS
$cshowsPrec :: forall i a. (Show i, Show a) => Int -> FinalResult i a -> ShowS
Show)

finalizeResult ::
    IResult i a -- ^ Must be either 'Done' or 'Fail', not 'Partial'
    -> FinalResult i a
finalizeResult :: forall i a. IResult i a -> FinalResult i a
finalizeResult IResult i a
r = case IResult i a
r of
    Done i
remainder a
v ->
        forall i a. i -> Either ParseError a -> FinalResult i a
FinalResult i
remainder (forall a b. b -> Either a b
Right a
v)
    Fail i
remainder [String]
context String
message ->
        forall i a. i -> Either ParseError a -> FinalResult i a
FinalResult i
remainder (forall a b. a -> Either a b
Left ([String] -> String -> ParseError
ParseError [String]
context String
message))
    Partial{} ->
        forall a. HasCallStack => String -> a
error String
"parseWith should not return Partial"

data ParseError = ParseError
    [String] -- ^ A list of contexts in which the error occurred
    String -- ^ The message describing the error, if any
    deriving (ParseError -> ParseError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParseError -> ParseError -> Bool
$c/= :: ParseError -> ParseError -> Bool
== :: ParseError -> ParseError -> Bool
$c== :: ParseError -> ParseError -> Bool
Eq, Eq ParseError
ParseError -> ParseError -> Bool
ParseError -> ParseError -> Ordering
ParseError -> ParseError -> ParseError
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ParseError -> ParseError -> ParseError
$cmin :: ParseError -> ParseError -> ParseError
max :: ParseError -> ParseError -> ParseError
$cmax :: ParseError -> ParseError -> ParseError
>= :: ParseError -> ParseError -> Bool
$c>= :: ParseError -> ParseError -> Bool
> :: ParseError -> ParseError -> Bool
$c> :: ParseError -> ParseError -> Bool
<= :: ParseError -> ParseError -> Bool
$c<= :: ParseError -> ParseError -> Bool
< :: ParseError -> ParseError -> Bool
$c< :: ParseError -> ParseError -> Bool
compare :: ParseError -> ParseError -> Ordering
$ccompare :: ParseError -> ParseError -> Ordering
Ord, Int -> ParseError -> ShowS
[ParseError] -> ShowS
ParseError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseError] -> ShowS
$cshowList :: [ParseError] -> ShowS
show :: ParseError -> String
$cshow :: ParseError -> String
showsPrec :: Int -> ParseError -> ShowS
$cshowsPrec :: Int -> ParseError -> ShowS
Show)

-- | Format a parse error in a matter suitable for displaying in log output
showParseError :: ParseError -> String
showParseError :: ParseError -> String
showParseError (ParseError [String]
context String
message)
    | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
context = String
message
    | Bool
otherwise = forall a. [a] -> [[a]] -> [a]
intercalate String
" > " [String]
context forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ String
message

data BufferedInput m i = BufferedInput
    i -- ^ Initial input
    (m i) -- ^ Should return an empty string once the end of input is reached

data RestorableInput m i = RestorableInput
    (m i) -- ^ Return an empty string once the end of input is reached
    (i -> m ()) -- ^ Return a non-empty chunk of input to the input stream