-- |
-- This module contains internal extensions to Data.Text.
--
module Data.Text.PureScript (spanUpTo) where

import Prelude

import Data.Text.Internal (Text(..), text)
import Data.Text.Unsafe (Iter(..), iter)

-- | /O(n)/ 'spanUpTo', applied to a number @n@, predicate @p@, and text @t@,
-- returns a pair whose first element is the longest prefix (possibly empty) of
-- @t@ of length less than or equal to @n@ of elements that satisfy @p@, and
-- whose second is the remainder of the text.
{-# INLINE spanUpTo #-}
spanUpTo :: Int -> (Char -> Bool) -> Text -> (Text, Text)
spanUpTo :: Int -> (Char -> Bool) -> Text -> (Text, Text)
spanUpTo Int
n Char -> Bool
p t :: Text
t@(Text Array
arr Int
off Int
len) = (Text
hd, Text
tl)
  where hd :: Text
hd = Array -> Int -> Int -> Text
text Array
arr Int
off Int
k
        tl :: Text
tl = Array -> Int -> Int -> Text
text Array
arr (Int
off forall a. Num a => a -> a -> a
+ Int
k) (Int
len forall a. Num a => a -> a -> a
- Int
k)
        !k :: Int
k = Int -> Int -> Int
loop Int
n Int
0
        loop :: Int -> Int -> Int
loop !Int
n' !Int
i | Int
n' forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
len Bool -> Bool -> Bool
&& Char -> Bool
p Char
c = Int -> Int -> Int
loop (Int
n' forall a. Num a => a -> a -> a
- Int
1) (Int
i forall a. Num a => a -> a -> a
+ Int
d)
                    | Bool
otherwise                = Int
i
            where Iter Char
c Int
d = Text -> Int -> Iter
iter Text
t Int
i