@@ -74,6 +74,7 @@ module Streamly.Internal.Data.Parser.ParserD
74 -- Separators
74 -- Separators
75 , takeEndBy
75 , takeEndBy
76 , takeEndBy_
76 , takeEndBy_
77 , takeStartBy
78 , takeStartBy
79 -- Words and grouping
80 -- Words and grouping
@@ -190,6 +191,7 @@ where
190import Control.Exception (assert, Exception)
191import Control.Exception (assert, Exception)
191import Control.Monad (when)
192import Control.Monad (when)
192import Control.Monad.Catch (MonadCatch, MonadThrow(..))
193import Control.Monad.Catch (MonadCatch, MonadThrow(..))
194+import Data.Bifunctor (first)
193import Fusion.Plugin.Types (Fuse(..))
195import Fusion.Plugin.Types (Fuse(..))
194import Streamly.Internal.Data.Fold.Type (Fold(..))
196import Streamly.Internal.Data.Fold.Type (Fold(..))
195import Streamly.Internal.Data.SVar.Type (defState)
197import Streamly.Internal.Data.SVar.Type (defState)
@@ -687,12 +689,39 @@ takeEndBy cond (Parser pstep pinitial pextract) =
687 res <- pstep s a
689 res <- pstep s a
688 if not (cond a)
690 if not (cond a)
689 then return res
691 then return res
692+ else extractStep pextract res
694+-- | See 'Streamly.Internal.Data.Parser.takeEndByEsc'.
698+{-# INLINE takeEndByEsc #-}
699+takeEndByEsc :: MonadCatch m =>
700+ (a -> Bool) -> (a -> Bool) -> Parser m a b -> Parser m a b
701+takeEndByEsc isEsc isSep (Parser pstep pinitial pextract) =
703+ Parser step initial extract
707+ initial = first Left <$> pinitial
709+ step (Left s) a = do
711+ then return $ Partial 0 $ Right s
691− case res of
713+ res <- pstep s a
692− Partial n s1 -> Done n <$> pextract s1
714+ if not (isSep a)
693− Done n b -> return $ Done n b
715+ then return $ mapStateStep Left res
694− Continue n s1 -> Done n <$> pextract s1
716+ else extractStep pextract res
695− Error _ -> return res
717+
718+ step (Right s) a = do
720+ return $ mapStateStep Left res
722+ extract (Left s) = pextract s
724+ throwM $ ParseError "takeEndByEsc: trailing escape, end of input"
697-- | See 'Streamly.Internal.Data.Parser.takeEndBy_'.
726-- | See 'Streamly.Internal.Data.Parser.takeEndBy_'.