{-# LANGUAGE BangPatterns #-}
module Text.Parsix.Internal where
import qualified Data.IntervalMap.FingerTree as IntervalMap
import Data.Text(Text)
import qualified Data.Text.Unsafe as Unsafe
codeUnitSlice :: Int -> Int -> Text -> Text
codeUnitSlice start end text
= Unsafe.takeWord16 (end' - start')
$ Unsafe.dropWord16 start' text
where
start' = clamp start
end' = clamp end
clamp x = max 0 $ min x $ Unsafe.lengthWord16 text
nextNewline :: Text -> Int -> Int
nextNewline inp i = go inp i'
where
i' = max 0 i
go text index
| index >= len = len
| otherwise = case Unsafe.iter text index of
Unsafe.Iter '\n' _ -> index
Unsafe.Iter _ delta -> nextNewline text $ index + delta
where
len = Unsafe.lengthWord16 text
prevNewline :: Text -> Int -> Int
prevNewline inp i = go inp (i' - 1) + 1
where
i' = min i $ Unsafe.lengthWord16 inp
go text index
| index < 0 = -1
| otherwise = case Unsafe.reverseIter text index of
('\n', _) -> index
(_, delta) -> go text $ index + delta
rightOpen :: Int -> Int -> IntervalMap.Interval Int
rightOpen !start !end = IntervalMap.Interval start $! end - 1
rightOpenView :: IntervalMap.Interval Int -> (Int, Int)
rightOpenView (IntervalMap.Interval !start !end) = (,) start $! end + 1