module Scanner.Attoparsec
( atto
, toAtto
)
where
import qualified Scanner
import Scanner.Internal (Scanner (Scanner))
import Data.Maybe
import qualified Data.ByteString as ByteString
import qualified Data.Attoparsec.ByteString as Atto
{-# INLINE atto #-}
atto :: Atto.Parser a -> Scanner a
atto :: Parser a -> Scanner a
atto Parser a
p = (forall r. ByteString -> Next a r -> Result r) -> Scanner a
forall a.
(forall r. ByteString -> Next a r -> Result r) -> Scanner a
Scanner ((forall r. ByteString -> Next a r -> Result r) -> Scanner a)
-> (forall r. ByteString -> Next a r -> Result r) -> Scanner a
forall a b. (a -> b) -> a -> b
$ \ByteString
bs Next a r
next ->
case Parser a -> ByteString -> Result a
forall a. Parser a -> ByteString -> Result a
Atto.parse Parser a
p ByteString
bs of
Atto.Done ByteString
bs' a
r -> Next a r
next ByteString
bs' a
r
Atto.Fail ByteString
bs' [String]
_ String
err -> ByteString -> String -> Result r
forall r. ByteString -> String -> Result r
Scanner.Fail ByteString
bs' String
err
Atto.Partial ByteString -> Result a
cont -> (ByteString -> Result a) -> Next a r -> Result r
forall t r.
(ByteString -> IResult ByteString t)
-> (ByteString -> t -> Result r) -> Result r
slowPath ByteString -> Result a
cont Next a r
next
where
slowPath :: (ByteString -> IResult ByteString t)
-> (ByteString -> t -> Result r) -> Result r
slowPath ByteString -> IResult ByteString t
cont ByteString -> t -> Result r
next = (ByteString -> Result r) -> Result r
forall r. (ByteString -> Result r) -> Result r
Scanner.More ((ByteString -> Result r) -> Result r)
-> (ByteString -> Result r) -> Result r
forall a b. (a -> b) -> a -> b
$ \ByteString
bs ->
case ByteString -> IResult ByteString t
cont ByteString
bs of
Atto.Done ByteString
bs' t
r -> ByteString -> t -> Result r
next ByteString
bs' t
r
Atto.Fail ByteString
bs' [String]
_ String
err -> ByteString -> String -> Result r
forall r. ByteString -> String -> Result r
Scanner.Fail ByteString
bs' String
err
Atto.Partial ByteString -> IResult ByteString t
cont' -> (ByteString -> IResult ByteString t)
-> (ByteString -> t -> Result r) -> Result r
slowPath ByteString -> IResult ByteString t
cont' ByteString -> t -> Result r
next
toAtto :: Scanner a -> Atto.Parser a
toAtto :: Scanner a -> Parser a
toAtto Scanner a
s = (ByteString -> Result a) -> Parser a
forall b. (ByteString -> Result b) -> Parser ByteString b
go (Scanner a -> ByteString -> Result a
forall r. Scanner r -> ByteString -> Result r
Scanner.scan Scanner a
s)
where
go :: (ByteString -> Result b) -> Parser ByteString b
go ByteString -> Result b
run = do
ByteString
chunk <- ByteString -> Maybe ByteString -> ByteString
forall a. a -> Maybe a -> a
fromMaybe ByteString
ByteString.empty (Maybe ByteString -> ByteString)
-> Parser ByteString (Maybe ByteString)
-> Parser ByteString ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString (Maybe ByteString)
Atto.getChunk
case ByteString -> Result b
run ByteString
chunk of
Scanner.Done ByteString
bs b
r -> do
ByteString
_ <- Int -> Parser ByteString ByteString
Atto.take (ByteString -> Int
ByteString.length ByteString
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
bs)
b -> Parser ByteString b
forall (m :: * -> *) a. Monad m => a -> m a
return b
r
Scanner.Fail ByteString
bs String
msg -> do
ByteString
_ <- Int -> Parser ByteString ByteString
Atto.take (ByteString -> Int
ByteString.length ByteString
chunk Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
ByteString.length ByteString
bs)
String -> Parser ByteString b
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
msg
Scanner.More ByteString -> Result b
next -> do
ByteString
_ <- Int -> Parser ByteString ByteString
Atto.take (ByteString -> Int
ByteString.length ByteString
chunk)
(ByteString -> Result b) -> Parser ByteString b
go ByteString -> Result b
next