module Z.Data.Text.Extra (
cons, snoc
, uncons, unsnoc
, headMaybe, tailMayEmpty, lastMaybe, initMayEmpty
, head, tail, last, init
, inits, tails
, take, drop, takeR, dropR
, slice
, splitAt
, takeWhile, takeWhileR, dropWhile, dropWhileR, dropAround
, break, span
, breakR, spanR, breakOn, breakOnAll
, group, groupBy
, stripPrefix, stripSuffix
, split, splitWith, splitOn
, isPrefixOf, isSuffixOf, isInfixOf
, commonPrefix
, words, lines, unwords, unlines
, padLeft, padRight
, reverse
, intersperse
, intercalate
, intercalateElem
, transpose
) where
import Data.Primitive.PrimArray
import qualified Z.Data.Vector.Base as V
import qualified Z.Data.Vector.Extra as V
import qualified Z.Data.Vector.Search as V
import Data.Coerce
import qualified Data.List as List
import Z.Data.Text.Base
import Z.Data.Text.UTF8Codec
import Z.Data.Text.Search
import Control.Monad.ST
import Data.Char
import Data.Word
import Prelude hiding (concat, concatMap,
elem, notElem, null, length, map,
foldl, foldl1, foldr, foldr1,
maximum, minimum, product, sum,
all, any, replicate, traverse,
head, tail, init, last,
take, drop, splitAt,
takeWhile, dropWhile,
break, span, reverse,
words, lines, unwords, unlines)
cons :: Char -> Text -> Text
{-# INLINE cons #-}
cons :: Char -> Text -> Text
cons Char
c (Text (V.PrimVector PrimArray Word8
ba Int
s Int
l)) = Bytes -> Text
Text (forall (v :: * -> *) a.
(Vec v a, HasCallStack) =>
Int -> (forall s. MArr (IArray v) s a -> ST s Int) -> v a
V.createN (Int
4 forall a. Num a => a -> a -> a
+ Int
l) (\ MArr (IArray PrimVector) s Word8
mba -> do
Int
i <- forall (m :: * -> *).
PrimMonad m =>
MutablePrimArray (PrimState m) Word8 -> Int -> Char -> m Int
encodeChar MArr (IArray PrimVector) s Word8
mba Int
0 Char
c
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MArr (IArray PrimVector) s Word8
mba Int
i PrimArray Word8
ba Int
s Int
l
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Int
i forall a. Num a => a -> a -> a
+ Int
l))
snoc :: Text -> Char -> Text
{-# INLINE snoc #-}
snoc :: Text -> Char -> Text
snoc (Text (V.PrimVector PrimArray Word8
ba Int
s Int
l)) Char
c = Bytes -> Text
Text (forall (v :: * -> *) a.
(Vec v a, HasCallStack) =>
Int -> (forall s. MArr (IArray v) s a -> ST s Int) -> v a
V.createN (Int
4 forall a. Num a => a -> a -> a
+ Int
l) (\ MArr (IArray PrimVector) s Word8
mba -> do
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MArr (IArray PrimVector) s Word8
mba Int
0 PrimArray Word8
ba Int
s Int
l
forall (m :: * -> *).
PrimMonad m =>
MutablePrimArray (PrimState m) Word8 -> Int -> Char -> m Int
encodeChar MArr (IArray PrimVector) s Word8
mba Int
l Char
c))
uncons :: Text -> Maybe (Char, Text)
{-# INLINE uncons #-}
uncons :: Text -> Maybe (Char, Text)
uncons (Text (V.PrimVector PrimArray Word8
ba Int
s Int
l))
| Int
l forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. Maybe a
Nothing
| Bool
otherwise =
let (# Char
c, Int
i #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeChar PrimArray Word8
ba Int
s
in forall a. a -> Maybe a
Just (Char
c, Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba (Int
sforall a. Num a => a -> a -> a
+Int
i) (Int
lforall a. Num a => a -> a -> a
-Int
i)))
unsnoc :: Text -> Maybe (Text, Char)
{-# INLINE unsnoc #-}
unsnoc :: Text -> Maybe (Text, Char)
unsnoc (Text (V.PrimVector PrimArray Word8
ba Int
s Int
l))
| Int
l forall a. Eq a => a -> a -> Bool
== Int
0 = forall a. Maybe a
Nothing
| Bool
otherwise =
let (# Char
c, Int
i #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeCharReverse PrimArray Word8
ba (Int
s forall a. Num a => a -> a -> a
+ Int
l forall a. Num a => a -> a -> a
- Int
1)
in forall a. a -> Maybe a
Just (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
s (Int
lforall a. Num a => a -> a -> a
-Int
i)), Char
c)
head :: Text -> Char
{-# INLINE head #-}
head :: Text -> Char
head Text
t = case Text -> Maybe (Char, Text)
uncons Text
t of { Just (Char
c, Text
_) -> Char
c; Maybe (Char, Text)
_ -> forall a. HasCallStack => a
errorEmptyText }
tail :: Text -> Text
{-# INLINE tail #-}
tail :: Text -> Text
tail Text
t = case Text -> Maybe (Char, Text)
uncons Text
t of { Maybe (Char, Text)
Nothing -> forall a. HasCallStack => a
errorEmptyText; Just (Char
_, Text
t') -> Text
t' }
last :: Text -> Char
{-# INLINE last #-}
last :: Text -> Char
last Text
t = case Text -> Maybe (Text, Char)
unsnoc Text
t of { Just (Text
_, Char
c) -> Char
c; Maybe (Text, Char)
_ -> forall a. HasCallStack => a
errorEmptyText }
init :: Text -> Text
{-# INLINE init #-}
init :: Text -> Text
init Text
t = case Text -> Maybe (Text, Char)
unsnoc Text
t of { Just (Text
t', Char
_) -> Text
t'; Maybe (Text, Char)
_ -> forall a. HasCallStack => a
errorEmptyText }
headMaybe :: Text -> Maybe Char
{-# INLINE headMaybe #-}
headMaybe :: Text -> Maybe Char
headMaybe Text
t = case Text -> Maybe (Char, Text)
uncons Text
t of { Just (Char
c, Text
_) -> forall a. a -> Maybe a
Just Char
c; Maybe (Char, Text)
_ -> forall a. Maybe a
Nothing }
tailMayEmpty :: Text -> Text
{-# INLINE tailMayEmpty #-}
tailMayEmpty :: Text -> Text
tailMayEmpty Text
t = case Text -> Maybe (Char, Text)
uncons Text
t of { Maybe (Char, Text)
Nothing -> Text
empty; Just (Char
_, Text
t') -> Text
t' }
lastMaybe :: Text -> Maybe Char
{-# INLINE lastMaybe #-}
lastMaybe :: Text -> Maybe Char
lastMaybe Text
t = case Text -> Maybe (Text, Char)
unsnoc Text
t of { Just (Text
_, Char
c) -> forall a. a -> Maybe a
Just Char
c; Maybe (Text, Char)
_ -> forall a. Maybe a
Nothing }
initMayEmpty :: Text -> Text
{-# INLINE initMayEmpty #-}
initMayEmpty :: Text -> Text
initMayEmpty Text
t = case Text -> Maybe (Text, Char)
unsnoc Text
t of { Just (Text
t', Char
_) -> Text
t'; Maybe (Text, Char)
_ -> Text
empty }
inits :: Text -> [Text]
{-# INLINE inits #-}
inits :: Text -> [Text]
inits Text
t0 = Text -> [Text] -> [Text]
go Text
t0 [Text
t0]
where go :: Text -> [Text] -> [Text]
go Text
t [Text]
acc = case Text -> Maybe (Text, Char)
unsnoc Text
t of Just (Text
t', Char
_) -> Text -> [Text] -> [Text]
go Text
t' (Text
t'forall a. a -> [a] -> [a]
:[Text]
acc)
Maybe (Text, Char)
Nothing -> [Text]
acc
tails :: Text -> [Text]
{-# INLINE tails #-}
tails :: Text -> [Text]
tails Text
t = Text
t forall a. a -> [a] -> [a]
: case Text -> Maybe (Char, Text)
uncons Text
t of Just (Char
_, Text
t') -> Text -> [Text]
tails Text
t'
Maybe (Char, Text)
Nothing -> []
take :: Int -> Text -> Text
{-# INLINE take #-}
take :: Int -> Text -> Text
take Int
n t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
_))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
empty
| Bool
otherwise = case Text -> Int -> Int
charByteIndex Text
t Int
n of Int
i -> Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
s (Int
iforall a. Num a => a -> a -> a
-Int
s))
drop :: Int -> Text -> Text
{-# INLINE drop #-}
drop :: Int -> Text -> Text
drop Int
n t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
l))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
t
| Bool
otherwise = case Text -> Int -> Int
charByteIndex Text
t Int
n of Int
i -> Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
i (Int
lforall a. Num a => a -> a -> a
+Int
sforall a. Num a => a -> a -> a
-Int
i))
takeR :: Int -> Text -> Text
{-# INLINE takeR #-}
takeR :: Int -> Text -> Text
takeR Int
n t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
l))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
empty
| Bool
otherwise = case Text -> Int -> Int
charByteIndexR Text
t Int
n of Int
i -> Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba (Int
iforall a. Num a => a -> a -> a
+Int
1) (Int
sforall a. Num a => a -> a -> a
+Int
lforall a. Num a => a -> a -> a
-Int
1forall a. Num a => a -> a -> a
-Int
i))
dropR :: Int -> Text -> Text
{-# INLINE dropR #-}
dropR :: Int -> Text -> Text
dropR Int
n t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
_))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
t
| Bool
otherwise = case Text -> Int -> Int
charByteIndexR Text
t Int
n of Int
i -> Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
s (Int
iforall a. Num a => a -> a -> a
-Int
sforall a. Num a => a -> a -> a
+Int
1))
slice :: Int -> Int -> Text -> Text
{-# INLINE slice #-}
slice :: Int -> Int -> Text -> Text
slice Int
x Int
y Text
t | Int
y forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
empty
| Int
end forall a. Ord a => a -> a -> Bool
<= Int
0 = Text
empty
| Int
x forall a. Ord a => a -> a -> Bool
<= Int
0 = Int -> Text -> Text
take Int
end Text
t
| Bool
otherwise = Int -> Text -> Text
take Int
y (Int -> Text -> Text
drop Int
x Text
t)
where
!end :: Int
end = Int
x forall a. Num a => a -> a -> a
+ Int
y
splitAt :: Int -> Text -> (Text, Text)
{-# INLINE splitAt #-}
splitAt :: Int -> Text -> (Text, Text)
splitAt Int
n t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
l))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = (Text
empty, Text
t)
| Bool
otherwise = case Text -> Int -> Int
charByteIndex Text
t Int
n of
Int
i -> (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
s (Int
iforall a. Num a => a -> a -> a
-Int
s)), Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
ba Int
i (Int
sforall a. Num a => a -> a -> a
+Int
lforall a. Num a => a -> a -> a
-Int
i)))
takeWhile :: (Char -> Bool) -> Text -> Text
{-# INLINE takeWhile #-}
takeWhile :: (Char -> Bool) -> Text -> Text
takeWhile Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
_)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndex (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f) Text
t in Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s Int
i)
takeWhileR :: (Char -> Bool) -> Text -> Text
{-# INLINE takeWhileR #-}
takeWhileR :: (Char -> Bool) -> Text -> Text
takeWhileR Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
l)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndexR (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f) Text
t in Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr (Int
iforall a. Num a => a -> a -> a
+Int
s) (Int
lforall a. Num a => a -> a -> a
-Int
i))
dropWhile :: (Char -> Bool) -> Text -> Text
{-# INLINE dropWhile #-}
dropWhile :: (Char -> Bool) -> Text -> Text
dropWhile Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
_ Int
l)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndex (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f) Text
t in Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
i (Int
lforall a. Num a => a -> a -> a
-Int
i))
dropWhileR :: (Char -> Bool) -> Text -> Text
{-# INLINE dropWhileR #-}
dropWhileR :: (Char -> Bool) -> Text -> Text
dropWhileR Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
_)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndexR (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f) Text
t in Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s (Int
iforall a. Num a => a -> a -> a
-Int
s))
dropAround :: (Char -> Bool) -> Text -> Text
{-# INLINE dropAround #-}
dropAround :: (Char -> Bool) -> Text -> Text
dropAround Char -> Bool
f = (Char -> Bool) -> Text -> Text
dropWhileR Char -> Bool
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
dropWhile Char -> Bool
f
break :: (Char -> Bool) -> Text -> (Text, Text)
{-# INLINE break #-}
break :: (Char -> Bool) -> Text -> (Text, Text)
break Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
l)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndex Char -> Bool
f Text
t
in (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s Int
i), Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
i (Int
lforall a. Num a => a -> a -> a
-Int
i)))
span :: (Char -> Bool) -> Text -> (Text, Text)
{-# INLINE span #-}
span :: (Char -> Bool) -> Text -> (Text, Text)
span Char -> Bool
f = (Char -> Bool) -> Text -> (Text, Text)
break (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f)
breakR :: (Char -> Bool) -> Text -> (Text, Text)
{-# INLINE breakR #-}
breakR :: (Char -> Bool) -> Text -> (Text, Text)
breakR Char -> Bool
f t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
l)) =
let !i :: Int
i = (Char -> Bool) -> Text -> Int
findBytesIndexR Char -> Bool
f Text
t
in (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s Int
i), Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
i (Int
lforall a. Num a => a -> a -> a
-Int
i)))
spanR :: (Char -> Bool) -> Text -> (Text, Text)
{-# INLINE spanR #-}
spanR :: (Char -> Bool) -> Text -> (Text, Text)
spanR Char -> Bool
f = (Char -> Bool) -> Text -> (Text, Text)
breakR (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
f)
breakOn :: Text -> Text -> (Text, Text)
{-# INLINE breakOn #-}
breakOn :: Text -> Text -> (Text, Text)
breakOn (Text Bytes
needle) (Text Bytes
haystack) =
case forall (v :: * -> *) a. (Vec v a, Eq a) => v a -> v a -> (v a, v a)
V.breakOn Bytes
needle Bytes
haystack of (Bytes
v1, Bytes
v2) -> (Bytes -> Text
Text Bytes
v1, Bytes -> Text
Text Bytes
v2)
breakOnAll :: Text
-> Text
-> [(Text, Text)]
{-# INLINE breakOnAll #-}
breakOnAll :: Text -> Text -> [(Text, Text)]
breakOnAll (Text Bytes
needle) (Text haystack :: Bytes
haystack@(V.PrimVector PrimArray Word8
arr Int
s Int
l)) =
forall a b. (a -> b) -> [a] -> [b]
List.map Int -> (Text, Text)
breaker (forall (v :: * -> *) a.
(Vec v a, Eq a) =>
v a -> v a -> Bool -> [Int]
V.indices Bytes
needle Bytes
haystack Bool
False)
where
breaker :: Int -> (Text, Text)
breaker Int
i = (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s (Int
iforall a. Num a => a -> a -> a
-Int
s)), Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
i (Int
sforall a. Num a => a -> a -> a
+Int
lforall a. Num a => a -> a -> a
-Int
i)))
group :: Text -> [Text]
{-# INLINE group #-}
group :: Text -> [Text]
group = (Char -> Char -> Bool) -> Text -> [Text]
groupBy forall a. Eq a => a -> a -> Bool
(==)
groupBy :: (Char -> Char -> Bool) -> Text -> [Text]
{-# INLINABLE groupBy #-}
groupBy :: (Char -> Char -> Bool) -> Text -> [Text]
groupBy Char -> Char -> Bool
f (Text (V.PrimVector PrimArray Word8
arr Int
s Int
l))
| Int
l forall a. Eq a => a -> a -> Bool
== Int
0 = []
| Bool
otherwise = Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s (Int
s'forall a. Num a => a -> a -> a
-Int
s)) forall a. a -> [a] -> [a]
: (Char -> Char -> Bool) -> Text -> [Text]
groupBy Char -> Char -> Bool
f (Bytes -> Text
Text (forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s' (Int
lforall a. Num a => a -> a -> a
+Int
sforall a. Num a => a -> a -> a
-Int
s')))
where
(# Char
c0, Int
s0 #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeChar PrimArray Word8
arr Int
s
end :: Int
end = Int
s forall a. Num a => a -> a -> a
+ Int
l
s' :: Int
s' = PrimArray Word8 -> Int -> Int
go PrimArray Word8
arr (Int
sforall a. Num a => a -> a -> a
+Int
s0)
go :: PrimArray Word8 -> Int -> Int
go PrimArray Word8
arr' !Int
i
| Int
i forall a. Ord a => a -> a -> Bool
>= Int
end = Int
i
| Bool
otherwise = let (# Char
c1, Int
s1 #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeChar PrimArray Word8
arr' Int
i
in if Char -> Char -> Bool
f Char
c0 Char
c1 then PrimArray Word8 -> Int -> Int
go PrimArray Word8
arr' (Int
iforall a. Num a => a -> a -> a
+Int
s1) else Int
i
stripPrefix :: Text -> Text -> Maybe Text
{-# INLINABLE stripPrefix #-}
stripPrefix :: Text -> Text -> Maybe Text
stripPrefix = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a.
(Vec v a, Eq (v a)) =>
v a -> v a -> Maybe (v a)
V.stripPrefix @V.PrimVector @Word8)
stripSuffix :: Text -> Text -> Maybe Text
{-# INLINABLE stripSuffix #-}
stripSuffix :: Text -> Text -> Maybe Text
stripSuffix = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a.
(Vec v a, Eq (v a)) =>
v a -> v a -> Maybe (v a)
V.stripSuffix @V.PrimVector @Word8)
split :: Char -> Text -> [Text]
{-# INLINABLE split #-}
split :: Char -> Text -> [Text]
split Char
x = (Char -> Bool) -> Text -> [Text]
splitWith (forall a. Eq a => a -> a -> Bool
==Char
x)
splitWith :: (Char -> Bool) -> Text -> [Text]
{-# INLINABLE splitWith #-}
splitWith :: (Char -> Bool) -> Text -> [Text]
splitWith Char -> Bool
f (Text (V.PrimVector PrimArray Word8
arr Int
s Int
l)) = Int -> Int -> [Text]
go Int
s Int
s
where
!end :: Int
end = Int
s forall a. Num a => a -> a -> a
+ Int
l
go :: Int -> Int -> [Text]
go !Int
p !Int
q | Int
q forall a. Ord a => a -> a -> Bool
>= Int
end = let !v :: Bytes
v = forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
p (Int
qforall a. Num a => a -> a -> a
-Int
p) in [Bytes -> Text
Text Bytes
v]
| Char -> Bool
f Char
c = let !v :: Bytes
v = forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
p (Int
qforall a. Num a => a -> a -> a
-Int
p) in Bytes -> Text
Text Bytes
vforall a. a -> [a] -> [a]
:Int -> Int -> [Text]
go (Int
qforall a. Num a => a -> a -> a
+Int
n) (Int
qforall a. Num a => a -> a -> a
+Int
n)
| Bool
otherwise = Int -> Int -> [Text]
go Int
p (Int
qforall a. Num a => a -> a -> a
+Int
n)
where (# Char
c, Int
n #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeChar PrimArray Word8
arr Int
q
splitOn :: Text -> Text -> [Text]
{-# INLINABLE splitOn #-}
splitOn :: Text -> Text -> [Text]
splitOn = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a. (Vec v a, Eq a) => v a -> v a -> [v a]
V.splitOn @V.PrimVector @Word8)
isPrefixOf :: Text -> Text -> Bool
{-# INLINABLE isPrefixOf #-}
isPrefixOf :: Text -> Text -> Bool
isPrefixOf = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a. (Vec v a, Eq (v a)) => v a -> v a -> Bool
V.isPrefixOf @V.PrimVector @Word8)
isSuffixOf :: Text -> Text -> Bool
{-# INLINABLE isSuffixOf #-}
isSuffixOf :: Text -> Text -> Bool
isSuffixOf = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a. (Vec v a, Eq (v a)) => v a -> v a -> Bool
V.isSuffixOf @V.PrimVector @Word8)
isInfixOf :: Text -> Text -> Bool
{-# INLINABLE isInfixOf #-}
isInfixOf :: Text -> Text -> Bool
isInfixOf = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a. (Vec v a, Eq a) => v a -> v a -> Bool
V.isInfixOf @V.PrimVector @Word8)
commonPrefix :: Text -> Text -> (Text, Text, Text)
{-# INLINABLE commonPrefix #-}
commonPrefix :: Text -> Text -> (Text, Text, Text)
commonPrefix = coerce :: forall a b. Coercible a b => a -> b
coerce (forall (v :: * -> *) a.
(Vec v a, Eq a) =>
v a -> v a -> (v a, v a, v a)
V.commonPrefix @V.PrimVector @Word8)
words :: Text -> [Text]
{-# INLINABLE words #-}
words :: Text -> [Text]
words (Text (V.PrimVector PrimArray Word8
arr Int
s Int
l)) = Int -> Int -> [Text]
go Int
s Int
s
where
!end :: Int
end = Int
s forall a. Num a => a -> a -> a
+ Int
l
go :: Int -> Int -> [Text]
go !Int
s' !Int
i | Int
i forall a. Ord a => a -> a -> Bool
>= Int
end =
if Int
s' forall a. Eq a => a -> a -> Bool
== Int
end
then []
else let !v :: Bytes
v = forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s' (Int
endforall a. Num a => a -> a -> a
-Int
s') in [Bytes -> Text
Text Bytes
v]
| Bool
otherwise =
let (# Char
c, Int
n #) = PrimArray Word8 -> Int -> (# Char, Int #)
decodeChar PrimArray Word8
arr Int
i
in if Char -> Bool
isSpace Char
c
then if Int
s' forall a. Eq a => a -> a -> Bool
== Int
i
then Int -> Int -> [Text]
go (Int
iforall a. Num a => a -> a -> a
+Int
n) (Int
iforall a. Num a => a -> a -> a
+Int
n)
else let !v :: Bytes
v = forall a. PrimArray a -> Int -> Int -> PrimVector a
V.PrimVector PrimArray Word8
arr Int
s' (Int
iforall a. Num a => a -> a -> a
-Int
s') in Bytes -> Text
Text Bytes
v forall a. a -> [a] -> [a]
: Int -> Int -> [Text]
go (Int
iforall a. Num a => a -> a -> a
+Int
n) (Int
iforall a. Num a => a -> a -> a
+Int
n)
else Int -> Int -> [Text]
go Int
s' (Int
iforall a. Num a => a -> a -> a
+Int
n)
lines :: Text -> [Text]
{-# INLINABLE lines #-}
lines :: Text -> [Text]
lines = coerce :: forall a b. Coercible a b => a -> b
coerce Bytes -> [Bytes]
V.lines
unwords :: [Text] -> Text
{-# INLINABLE unwords #-}
unwords :: [Text] -> Text
unwords = coerce :: forall a b. Coercible a b => a -> b
coerce [Bytes] -> Bytes
V.unwords
unlines :: [Text] -> Text
{-# INLINABLE unlines #-}
unlines :: [Text] -> Text
unlines = coerce :: forall a b. Coercible a b => a -> b
coerce [Bytes] -> Bytes
V.unlines
padLeft :: Int -> Char -> Text -> Text
{-# INLINABLE padLeft #-}
padLeft :: Int -> Char -> Text -> Text
padLeft Int
n Char
c t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
l))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
tsiz = Text
t
| Bool
otherwise =
let psiz :: Int
psiz = (Int
nforall a. Num a => a -> a -> a
-Int
tsiz)forall a. Num a => a -> a -> a
*Int
csiz
siz :: Int
siz = Int
psiz forall a. Num a => a -> a -> a
+ Int
l
in Bytes -> Text
Text (forall (v :: * -> *) a.
Vec v a =>
Int -> (forall s. MArr (IArray v) s a -> ST s ()) -> v a
V.create Int
siz (\ MArr (IArray PrimVector) s Word8
marr -> do
Int
_ <- forall (m :: * -> *).
PrimMonad m =>
MutablePrimArray (PrimState m) Word8 -> Int -> Char -> m Int
encodeChar MArr (IArray PrimVector) s Word8
marr Int
0 Char
c
forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MArr (IArray PrimVector) s Word8
marr Int
csiz Int
psiz
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MArr (IArray PrimVector) s Word8
marr (Int
sizforall a. Num a => a -> a -> a
-Int
l) PrimArray Word8
arr Int
s Int
l))
where
tsiz :: Int
tsiz = Text -> Int
length Text
t
csiz :: Int
csiz = Char -> Int
encodeCharLength Char
c
go :: forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go :: forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MutablePrimArray s Word8
marr Int
s' Int
psiz
| Int
s' forall a. Ord a => a -> a -> Bool
>= Int
psiz = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> MutablePrimArray s Word8
-> Int
-> ST s ()
copyChar' Int
csiz MutablePrimArray s Word8
marr Int
s' MutablePrimArray s Word8
marr (Int
s'forall a. Num a => a -> a -> a
-Int
csiz) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MutablePrimArray s Word8
marr (Int
s'forall a. Num a => a -> a -> a
+Int
csiz) Int
psiz
padRight :: Int -> Char -> Text -> Text
{-# INLINABLE padRight #-}
padRight :: Int -> Char -> Text -> Text
padRight Int
n Char
c t :: Text
t@(Text (V.PrimVector PrimArray Word8
arr Int
s Int
l))
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
tsiz = Text
t
| Bool
otherwise =
let psiz :: Int
psiz = (Int
nforall a. Num a => a -> a -> a
-Int
tsiz)forall a. Num a => a -> a -> a
*Int
csiz
siz :: Int
siz = Int
psiz forall a. Num a => a -> a -> a
+ Int
l
in Bytes -> Text
Text (forall (v :: * -> *) a.
Vec v a =>
Int -> (forall s. MArr (IArray v) s a -> ST s ()) -> v a
V.create Int
siz (\ MArr (IArray PrimVector) s Word8
marr -> do
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray MArr (IArray PrimVector) s Word8
marr Int
0 PrimArray Word8
arr Int
s Int
l
Int
_ <- forall (m :: * -> *).
PrimMonad m =>
MutablePrimArray (PrimState m) Word8 -> Int -> Char -> m Int
encodeChar MArr (IArray PrimVector) s Word8
marr Int
l Char
c
forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MArr (IArray PrimVector) s Word8
marr (Int
lforall a. Num a => a -> a -> a
+Int
csiz) Int
siz))
where
tsiz :: Int
tsiz = Text -> Int
length Text
t
csiz :: Int
csiz = Char -> Int
encodeCharLength Char
c
go :: forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go :: forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MutablePrimArray s Word8
marr Int
s' Int
siz
| Int
s' forall a. Ord a => a -> a -> Bool
>= Int
siz = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> MutablePrimArray s Word8
-> Int
-> ST s ()
copyChar' Int
csiz MutablePrimArray s Word8
marr Int
s' MutablePrimArray s Word8
marr (Int
s'forall a. Num a => a -> a -> a
-Int
csiz) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s. MutablePrimArray s Word8 -> Int -> Int -> ST s ()
go MutablePrimArray s Word8
marr (Int
s'forall a. Num a => a -> a -> a
+Int
csiz) Int
siz
intersperse :: Char -> Text -> Text
{-# INLINABLE intersperse #-}
intersperse :: Char -> Text -> Text
intersperse Char
c = \ t :: Text
t@(Text (V.PrimVector PrimArray Word8
ba Int
s Int
l)) ->
let tlen :: Int
tlen = Text -> Int
length Text
t
in if Text -> Int
length Text
t forall a. Ord a => a -> a -> Bool
< Int
2
then Text
t
else (forall a. (forall s. ST s a) -> a
runST (do
MutablePrimArray s Word8
mbaC <- forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
4
Int
clen <- forall (m :: * -> *).
PrimMonad m =>
MutablePrimArray (PrimState m) Word8 -> Int -> Char -> m Int
encodeChar MutablePrimArray s Word8
mbaC Int
0 Char
c
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> m ()
shrinkMutablePrimArray MutablePrimArray s Word8
mbaC Int
clen
PrimArray Word8
baC <- forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s Word8
mbaC
let e :: Int
e = PrimArray Word8 -> Int -> Int
decodeCharLenReverse PrimArray Word8
ba (Int
sforall a. Num a => a -> a -> a
+Int
lforall a. Num a => a -> a -> a
-Int
1)
forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> Text
Text forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) a.
Vec v a =>
Int -> (forall s. MArr (IArray v) s a -> ST s ()) -> v a
V.create (Int
l forall a. Num a => a -> a -> a
+ (Int
tlenforall a. Num a => a -> a -> a
-Int
1) forall a. Num a => a -> a -> a
* Int
clen) (forall s.
PrimArray Word8
-> PrimArray Word8
-> Int
-> Int
-> Int
-> MutablePrimArray s Word8
-> ST s ()
go PrimArray Word8
baC PrimArray Word8
ba Int
s Int
0 (Int
sforall a. Num a => a -> a -> a
+Int
lforall a. Num a => a -> a -> a
-Int
e))
))
where
go :: PrimArray Word8
-> PrimArray Word8
-> Int
-> Int
-> Int
-> MutablePrimArray s Word8
-> ST s ()
go :: forall s.
PrimArray Word8
-> PrimArray Word8
-> Int
-> Int
-> Int
-> MutablePrimArray s Word8
-> ST s ()
go !PrimArray Word8
baC !PrimArray Word8
ba !Int
i !Int
j !Int
end !MutablePrimArray s Word8
mba
| Int
i forall a. Ord a => a -> a -> Bool
>= Int
end = do
let l :: Int
l = PrimArray Word8 -> Int -> Int
decodeCharLen PrimArray Word8
ba Int
i
forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> PrimArray Word8
-> Int
-> ST s ()
copyChar Int
l MutablePrimArray s Word8
mba Int
j PrimArray Word8
ba Int
i
| Bool
otherwise = do
let l :: Int
l = PrimArray Word8 -> Int -> Int
decodeCharLen PrimArray Word8
ba Int
i
forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> PrimArray Word8
-> Int
-> ST s ()
copyChar Int
l MutablePrimArray s Word8
mba Int
j PrimArray Word8
ba Int
i
let i' :: Int
i' = Int
i forall a. Num a => a -> a -> a
+ Int
l
j' :: Int
j' = Int
j forall a. Num a => a -> a -> a
+ Int
l
let clen :: Int
clen = forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray Word8
baC
forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> PrimArray Word8
-> Int
-> ST s ()
copyChar Int
clen MutablePrimArray s Word8
mba Int
j' PrimArray Word8
baC Int
0
forall s.
PrimArray Word8
-> PrimArray Word8
-> Int
-> Int
-> Int
-> MutablePrimArray s Word8
-> ST s ()
go PrimArray Word8
baC PrimArray Word8
ba Int
i' (Int
j'forall a. Num a => a -> a -> a
+Int
clen) Int
end MutablePrimArray s Word8
mba
reverse :: Text -> Text
{-# INLINABLE reverse #-}
reverse :: Text -> Text
reverse = \ (Text (V.PrimVector PrimArray Word8
ba Int
s Int
l)) -> Bytes -> Text
Text forall a b. (a -> b) -> a -> b
$ forall (v :: * -> *) a.
Vec v a =>
Int -> (forall s. MArr (IArray v) s a -> ST s ()) -> v a
V.create Int
l (forall s.
PrimArray Word8
-> Int -> Int -> Int -> MutablePrimArray s Word8 -> ST s ()
go PrimArray Word8
ba Int
s Int
l (Int
sforall a. Num a => a -> a -> a
+Int
l))
where
go :: PrimArray Word8 -> Int -> Int -> Int -> MutablePrimArray s Word8 -> ST s ()
go :: forall s.
PrimArray Word8
-> Int -> Int -> Int -> MutablePrimArray s Word8 -> ST s ()
go !PrimArray Word8
ba !Int
i !Int
j !Int
end !MutablePrimArray s Word8
mba
| Int
i forall a. Ord a => a -> a -> Bool
>= Int
end = forall (m :: * -> *) a. Monad m => a -> m a
return ()
| Bool
otherwise = do
let l :: Int
l = PrimArray Word8 -> Int -> Int
decodeCharLen PrimArray Word8
ba Int
i
j' :: Int
j' = Int
j forall a. Num a => a -> a -> a
- Int
l
forall s.
Int
-> MutablePrimArray s Word8
-> Int
-> PrimArray Word8
-> Int
-> ST s ()
copyChar Int
l MutablePrimArray s Word8
mba Int
j' PrimArray Word8
ba Int
i
forall s.
PrimArray Word8
-> Int -> Int -> Int -> MutablePrimArray s Word8 -> ST s ()
go PrimArray Word8
ba (Int
iforall a. Num a => a -> a -> a
+Int
l) Int
j' Int
end MutablePrimArray s Word8
mba
intercalate :: Text -> [Text] -> Text
{-# INLINABLE intercalate #-}
intercalate :: Text -> [Text] -> Text
intercalate Text
s = [Text] -> Text
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse Text
s
intercalateElem :: Char -> [Text] -> Text
{-# INLINABLE intercalateElem #-}
intercalateElem :: Char -> [Text] -> Text
intercalateElem Char
c = [Text] -> Text
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
List.intersperse (Char -> Text
singleton Char
c)
transpose :: [Text] -> [Text]
{-# INLINABLE transpose #-}
transpose :: [Text] -> [Text]
transpose [Text]
ts = forall a b. (a -> b) -> [a] -> [b]
List.map String -> Text
pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [[a]] -> [[a]]
List.transpose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map Text -> String
unpack forall a b. (a -> b) -> a -> b
$ [Text]
ts