{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module Data.Attoparsec.ByteString.Lazy
(
Result(..)
, module Data.Attoparsec.ByteString
, parse
, parseOnly
, parseTest
, maybeResult
, eitherResult
) where
import Control.DeepSeq (NFData(rnf))
import Data.ByteString.Lazy.Internal (ByteString(..), chunk)
import Data.List (intercalate)
import qualified Data.ByteString as B
import qualified Data.Attoparsec.ByteString as A
import qualified Data.Attoparsec.Internal.Types as T
import Data.Attoparsec.ByteString
hiding (IResult(..), Result, eitherResult, maybeResult,
parse, parseOnly, parseWith, parseTest)
data Result r = Fail ByteString [String] String
| Done ByteString r
instance NFData r => NFData (Result r) where
rnf :: Result r -> ()
rnf (Fail ByteString
bs [String]
ctxs String
msg) = ByteString -> ()
rnfBS ByteString
bs () -> () -> ()
forall a b. a -> b -> b
`seq` [String] -> ()
forall a. NFData a => a -> ()
rnf [String]
ctxs () -> () -> ()
forall a b. a -> b -> b
`seq` String -> ()
forall a. NFData a => a -> ()
rnf String
msg
rnf (Done ByteString
bs r
r) = ByteString -> ()
rnfBS ByteString
bs () -> () -> ()
forall a b. a -> b -> b
`seq` r -> ()
forall a. NFData a => a -> ()
rnf r
r
{-# INLINE rnf #-}
rnfBS :: ByteString -> ()
rnfBS :: ByteString -> ()
rnfBS (Chunk ByteString
_ ByteString
xs) = ByteString -> ()
rnfBS ByteString
xs
rnfBS ByteString
Empty = ()
{-# INLINE rnfBS #-}
instance Show r => Show (Result r) where
show :: Result r -> String
show (Fail ByteString
bs [String]
stk String
msg) =
String
"Fail " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteString -> String
forall a. Show a => a -> String
show ByteString
bs String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
forall a. Show a => a -> String
show [String]
stk String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
msg
show (Done ByteString
bs r
r) = String
"Done " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteString -> String
forall a. Show a => a -> String
show ByteString
bs String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ r -> String
forall a. Show a => a -> String
show r
r
fmapR :: (a -> b) -> Result a -> Result b
fmapR :: forall a b. (a -> b) -> Result a -> Result b
fmapR a -> b
_ (Fail ByteString
st [String]
stk String
msg) = ByteString -> [String] -> String -> Result b
forall r. ByteString -> [String] -> String -> Result r
Fail ByteString
st [String]
stk String
msg
fmapR a -> b
f (Done ByteString
bs a
r) = ByteString -> b -> Result b
forall r. ByteString -> r -> Result r
Done ByteString
bs (a -> b
f a
r)
instance Functor Result where
fmap :: forall a b. (a -> b) -> Result a -> Result b
fmap = (a -> b) -> Result a -> Result b
forall a b. (a -> b) -> Result a -> Result b
fmapR
parse :: A.Parser a -> ByteString -> Result a
parse :: forall a. Parser a -> ByteString -> Result a
parse Parser a
p ByteString
s = case ByteString
s of
Chunk ByteString
x ByteString
xs -> IResult ByteString a -> ByteString -> Result a
forall {r}. IResult ByteString r -> ByteString -> Result r
go (Parser a -> ByteString -> IResult ByteString a
forall a. Parser a -> ByteString -> Result a
A.parse Parser a
p ByteString
x) ByteString
xs
ByteString
empty -> IResult ByteString a -> ByteString -> Result a
forall {r}. IResult ByteString r -> ByteString -> Result r
go (Parser a -> ByteString -> IResult ByteString a
forall a. Parser a -> ByteString -> Result a
A.parse Parser a
p ByteString
B.empty) ByteString
empty
where
go :: IResult ByteString r -> ByteString -> Result r
go (T.Fail ByteString
x [String]
stk String
msg) ByteString
ys = ByteString -> [String] -> String -> Result r
forall r. ByteString -> [String] -> String -> Result r
Fail (ByteString -> ByteString -> ByteString
chunk ByteString
x ByteString
ys) [String]
stk String
msg
go (T.Done ByteString
x r
r) ByteString
ys = ByteString -> r -> Result r
forall r. ByteString -> r -> Result r
Done (ByteString -> ByteString -> ByteString
chunk ByteString
x ByteString
ys) r
r
go (T.Partial ByteString -> IResult ByteString r
k) (Chunk ByteString
y ByteString
ys) = IResult ByteString r -> ByteString -> Result r
go (ByteString -> IResult ByteString r
k ByteString
y) ByteString
ys
go (T.Partial ByteString -> IResult ByteString r
k) ByteString
empty = IResult ByteString r -> ByteString -> Result r
go (ByteString -> IResult ByteString r
k ByteString
B.empty) ByteString
empty
parseTest :: (Show a) => A.Parser a -> 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)
maybeResult :: Result r -> Maybe r
maybeResult :: forall r. Result r -> Maybe r
maybeResult (Done ByteString
_ r
r) = r -> Maybe r
forall a. a -> Maybe a
Just r
r
maybeResult Result r
_ = Maybe r
forall a. Maybe a
Nothing
eitherResult :: Result r -> Either String r
eitherResult :: forall r. Result r -> Either String r
eitherResult (Done ByteString
_ r
r) = r -> Either String r
forall a b. b -> Either a b
Right r
r
eitherResult (Fail ByteString
_ [] String
msg) = String -> Either String r
forall a b. a -> Either a b
Left String
msg
eitherResult (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 -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
msg)
parseOnly :: A.Parser a -> ByteString -> Either String a
parseOnly :: forall a. Parser a -> ByteString -> Either String a
parseOnly Parser a
p = Result a -> Either String a
forall r. Result r -> Either String r
eitherResult (Result a -> Either String a)
-> (ByteString -> Result a) -> ByteString -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser a -> ByteString -> Result a
forall a. Parser a -> ByteString -> Result a
parse Parser a
p
{-# INLINE parseOnly #-}