#if __GLASGOW_HASKELL__ >= 702
#endif
module Data.Attoparsec.ByteString.Lazy
(
Result(..)
, module Data.Attoparsec.ByteString
, parse
, 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, parseWith, parseTest)
data Result r = Fail ByteString [String] String
| Done ByteString r
instance NFData r => NFData (Result r) where
rnf (Fail bs ctxs msg) = rnfBS bs `seq` rnf ctxs `seq` rnf msg
rnf (Done bs r) = rnfBS bs `seq` rnf r
rnfBS :: ByteString -> ()
rnfBS (Chunk _ xs) = rnfBS xs
rnfBS Empty = ()
instance Show r => Show (Result r) where
show (Fail bs stk msg) =
"Fail " ++ show bs ++ " " ++ show stk ++ " " ++ show msg
show (Done bs r) = "Done " ++ show bs ++ " " ++ show r
fmapR :: (a -> b) -> Result a -> Result b
fmapR _ (Fail st stk msg) = Fail st stk msg
fmapR f (Done bs r) = Done bs (f r)
instance Functor Result where
fmap = fmapR
parse :: A.Parser a -> ByteString -> Result a
parse p s = case s of
Chunk x xs -> go (A.parse p x) xs
empty -> go (A.parse p B.empty) empty
where
go (T.Fail x stk msg) ys = Fail (chunk x ys) stk msg
go (T.Done x r) ys = Done (chunk x ys) r
go (T.Partial k) (Chunk y ys) = go (k y) ys
go (T.Partial k) empty = go (k B.empty) empty
parseTest :: (Show a) => A.Parser a -> ByteString -> IO ()
parseTest p s = print (parse p s)
maybeResult :: Result r -> Maybe r
maybeResult (Done _ r) = Just r
maybeResult _ = Nothing
eitherResult :: Result r -> Either String r
eitherResult (Done _ r) = Right r
eitherResult (Fail _ [] msg) = Left msg
eitherResult (Fail _ ctxs msg) = Left (intercalate " > " ctxs ++ ": " ++ msg)