module Mikan.Utils.Text
(
breakAfter
, spanEnd
) where
import Prelude
( Char, Bool, Int
, Ord(..), Num(..)
, fromIntegral, divMod
, Applicative(..), Monad(..)
, otherwise
)
import Prelude qualified
import Control.Monad.ST
import Data.Primitive.ByteArray
import Data.Text
import Data.Text.Internal
import Data.Text.Unsafe
import Data.Word
{-# INLINE breakAfter #-}
breakAfter :: (Char -> Bool) -> Text -> (Text, Text)
breakAfter :: (Char -> Bool) -> Text -> (Text, Text)
breakAfter Char -> Bool
p t :: Text
t@(Text Array
arr Int
off Int
len) = (Text
hd, Text
tl) where
!k :: Int
k = Int -> Int
loop Int
0
!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 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
k) (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
k)
loop :: Int -> Int
loop !Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len = case Array -> Int -> Iter
iterArray Array
arr (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) of
Iter Char
c Int
d
| Char -> Bool
p Char
c -> Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
| Bool
otherwise -> Int -> Int
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
d)
| Bool
otherwise = Int
i
{-# INLINE spanEnd #-}
spanEnd :: (Char -> Bool) -> Text -> (Text, Text)
spanEnd :: (Char -> Bool) -> Text -> (Text, Text)
spanEnd Char -> Bool
p t :: Text
t@(Text Array
arr Int
off Int
len) = Int -> (Text, Text)
loop (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) where
loop :: Int -> (Text, Text)
loop !Int
i
| Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i = case Array -> Int -> Iter
reverseIterArray Array
arr (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) of
Iter Char
c Int
l
| Char -> Bool
p Char
c -> Int -> (Text, Text)
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l)
| Bool
otherwise -> (Array -> Int -> Int -> Text
text Array
arr Int
off (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1), Array -> Int -> Int -> Text
text Array
arr (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
| Bool
otherwise = (Text
empty, Text
t)