potoki-core-2.3.4.1: library/Potoki/Core/Transform/Scanner.hs
module Potoki.Core.Transform.Scanner
where
import Potoki.Core.Prelude hiding (take, takeWhile, filter, drop)
import Potoki.Core.Types
import Potoki.Core.Transform.Basic
import Scanner
{-# INLINE scan #-}
scan :: Scanner a -> Transform ByteString (Either Text a)
scan scanner =
Transform $ \ (Fetch fetchIo) -> liftIO $ do
unconsumedRef <- newMutVar mempty
finishedRef <- newMutVar False
return $ Fetch $ let
matchResult =
\ case
More inputToResultVal ->
consumeVal inputToResultVal
Done unconsumed parsed ->
do
writeMutVar unconsumedRef unconsumed
return (Just (Right parsed))
Fail unconsumed message ->
do
writeMutVar unconsumedRef unconsumed
writeMutVar finishedRef True
return (Just (Left (fromString message)))
consumeVal inputToResultVal' =
fetchIo >>= \ case
Nothing -> do
writeMutVar finishedRef True
matchResult (inputToResultVal' mempty)
Just input -> do
when (input == mempty) (writeMutVar finishedRef True)
matchResult (inputToResultVal' input)
in do
finished <- readMutVar finishedRef
if finished
then return Nothing
else do
unconsumed <- readMutVar unconsumedRef
if unconsumed == mempty
then
fetchIo >>= \ case
Nothing -> return Nothing
Just input -> do
if input == mempty
then return Nothing
else matchResult (Scanner.scan scanner input)
else do
writeMutVar unconsumedRef mempty
matchResult (Scanner.scan scanner unconsumed)