@@ -43,7 +43,7 @@ module Streamly.Internal.Data.Parser.ParserD
4343 -- takeWhileBetween cond m n p = takeWhile cond (takeBetween m n p)
4444 --
4545 -- Grab a sequence of input elements without inspecting them
46− -- , takeBetween
46+ , takeBetween
4747 -- , takeLE -- take -- takeBetween 0 n
4848 -- , takeLE1 -- take1 -- takeBetween 1 n
4949 , takeEQ -- takeBetween n n
@@ -281,6 +281,59 @@ either parser = Parser step initial extract
281281-- Taking elements
282282-------------------------------------------------------------------------------
283283
284+-- | See 'Streamly.Internal.Data.Parser.takeBetween'.
285+--
286+-- /Internal/
287+--
288+{-# INLINE takeBetween #-}
289+takeBetween :: MonadCatch m => Int -> Int -> Fold m a b -> Parser m a b
290+takeBetween low high (Fold fstep finitial fextract) =
291+
292+ Parser step initial extract
293+
294+ where
295+
296+ initial = Tuple' 0 <$> finitial
297+
298+ step (Tuple' i s) a
299+ | low > high = throwM $ ParseError
300+ $ "takeBetween: lower bound - " ++ show low
301+ ++ " is greater than higher bound - " ++ show high
302+ | high <= 0 = Done 1 <$> fextract s
303+ | i1 < low = do
304+ res <- fstep s a
305+ return
306+ $ case res of
307+ FL.Partial s' -> Continue 0 $ Tuple' i1 s'
308+ FL.Done _ ->
309+ Error
310+ $ "takeBetween: the collecting fold terminated after"
311+ ++ " consuming" ++ show i1 ++ " elements"
312+ | otherwise = do
313+ res <- fstep s a
314+ case res of
315+ FL.Partial s' ->
316+ if i1 >= high
317+ then Done 0 <$> fextract s'
318+ else return $ Partial 0 $ Tuple' i1 s'
319+ FL.Done b -> return $ Done 0 b
320+
321+ where
322+
323+ i1 = i +1
324+
325+ extract (Tuple' i s)
326+ | i >= low && i <= high = fextract s
327+ | otherwise = throwM $ ParseError err
328+
329+ where
330+
331+ err =
332+ "takeBetween: Expecting alteast " ++ show low
333+ ++ " elements, got " ++ show i
334+
335+
336+
284337-- | See 'Streamly.Internal.Data.Parser.takeEQ'.
285338--
286339-- /Internal/