{-# LANGUAGE BangPatterns, RecordWildCards, CPP #-}
module Data.Text.ICU.Break.Pure
(
Breaker
, Break
, brkPrefix
, brkBreak
, brkSuffix
, brkStatus
, Line(..)
, Data.Text.ICU.Break.Word(..)
, breakCharacter
, breakLine
, breakSentence
, breakWord
, breaks
, breaksRight
) where
import Control.DeepSeq (NFData(..))
import Data.Text (Text, empty)
import Data.Text.ICU.Break (Line, Word)
import Data.Text.ICU.Break.Types (BreakIterator(..))
import Data.Text.ICU.Internal (LocaleName, takeWord, dropWord)
import System.IO.Unsafe (unsafeInterleaveIO, unsafePerformIO)
import qualified Data.Text.ICU.Break as IO
newtype Breaker a = B (BreakIterator a)
new :: (LocaleName -> Text -> IO (BreakIterator a)) -> LocaleName -> Breaker a
new :: forall a.
(LocaleName -> Text -> IO (BreakIterator a))
-> LocaleName -> Breaker a
new LocaleName -> Text -> IO (BreakIterator a)
act LocaleName
loc = IO (Breaker a) -> Breaker a
forall a. IO a -> a
unsafePerformIO (IO (Breaker a) -> Breaker a) -> IO (Breaker a) -> Breaker a
forall a b. (a -> b) -> a -> b
$ BreakIterator a -> Breaker a
forall a. BreakIterator a -> Breaker a
B (BreakIterator a -> Breaker a)
-> IO (BreakIterator a) -> IO (Breaker a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` LocaleName -> Text -> IO (BreakIterator a)
act LocaleName
loc Text
empty
breakCharacter :: LocaleName -> Breaker ()
breakCharacter :: LocaleName -> Breaker ()
breakCharacter = (LocaleName -> Text -> IO (BreakIterator ()))
-> LocaleName -> Breaker ()
forall a.
(LocaleName -> Text -> IO (BreakIterator a))
-> LocaleName -> Breaker a
new LocaleName -> Text -> IO (BreakIterator ())
IO.breakCharacter
breakLine :: LocaleName -> Breaker Line
breakLine :: LocaleName -> Breaker Line
breakLine = (LocaleName -> Text -> IO (BreakIterator Line))
-> LocaleName -> Breaker Line
forall a.
(LocaleName -> Text -> IO (BreakIterator a))
-> LocaleName -> Breaker a
new LocaleName -> Text -> IO (BreakIterator Line)
IO.breakLine
breakSentence :: LocaleName -> Breaker ()
breakSentence :: LocaleName -> Breaker ()
breakSentence = (LocaleName -> Text -> IO (BreakIterator ()))
-> LocaleName -> Breaker ()
forall a.
(LocaleName -> Text -> IO (BreakIterator a))
-> LocaleName -> Breaker a
new LocaleName -> Text -> IO (BreakIterator ())
IO.breakSentence
breakWord :: LocaleName -> Breaker Data.Text.ICU.Break.Word
breakWord :: LocaleName -> Breaker Word
breakWord = (LocaleName -> Text -> IO (BreakIterator Word))
-> LocaleName -> Breaker Word
forall a.
(LocaleName -> Text -> IO (BreakIterator a))
-> LocaleName -> Breaker a
new LocaleName -> Text -> IO (BreakIterator Word)
IO.breakWord
data Break a = Break {
forall a. Break a -> Text
brkPrefix :: {-# UNPACK #-} !Text
, forall a. Break a -> Text
brkBreak :: {-# UNPACK #-} !Text
, forall a. Break a -> Text
brkSuffix :: {-# UNPACK #-} !Text
, forall a. Break a -> a
brkStatus :: !a
} deriving (Break a -> Break a -> Bool
(Break a -> Break a -> Bool)
-> (Break a -> Break a -> Bool) -> Eq (Break a)
forall a. Eq a => Break a -> Break a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Break a -> Break a -> Bool
== :: Break a -> Break a -> Bool
$c/= :: forall a. Eq a => Break a -> Break a -> Bool
/= :: Break a -> Break a -> Bool
Eq, Int -> Break a -> ShowS
[Break a] -> ShowS
Break a -> String
(Int -> Break a -> ShowS)
-> (Break a -> String) -> ([Break a] -> ShowS) -> Show (Break a)
forall a. Show a => Int -> Break a -> ShowS
forall a. Show a => [Break a] -> ShowS
forall a. Show a => Break a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Break a -> ShowS
showsPrec :: Int -> Break a -> ShowS
$cshow :: forall a. Show a => Break a -> String
show :: Break a -> String
$cshowList :: forall a. Show a => [Break a] -> ShowS
showList :: [Break a] -> ShowS
Show)
instance (NFData a) => NFData (Break a) where
rnf :: Break a -> ()
rnf Break{a
Text
brkPrefix :: forall a. Break a -> Text
brkBreak :: forall a. Break a -> Text
brkSuffix :: forall a. Break a -> Text
brkStatus :: forall a. Break a -> a
brkPrefix :: Text
brkBreak :: Text
brkSuffix :: Text
brkStatus :: a
..} = a -> ()
forall a. NFData a => a -> ()
rnf a
brkStatus
breaks :: Breaker a -> Text -> [Break a]
breaks :: forall a. Breaker a -> Text -> [Break a]
breaks (B BreakIterator a
b) Text
t = IO [Break a] -> [Break a]
forall a. IO a -> a
unsafePerformIO (IO [Break a] -> [Break a]) -> IO [Break a] -> [Break a]
forall a b. (a -> b) -> a -> b
$ do
bi <- BreakIterator a -> IO (BreakIterator a)
forall a. BreakIterator a -> IO (BreakIterator a)
IO.clone BreakIterator a
b
IO.setText bi t
let go TextI
p = do
mix <- BreakIterator a -> IO (Maybe TextI)
forall a. BreakIterator a -> IO (Maybe TextI)
IO.next BreakIterator a
bi
case mix of
Maybe TextI
Nothing -> [Break a] -> IO [Break a]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just TextI
n -> do
s <- BreakIterator a -> IO a
forall a. BreakIterator a -> IO a
IO.getStatus BreakIterator a
bi
let d = TextI
nTextI -> TextI -> TextI
forall a. Num a => a -> a -> a
-TextI
p
u = TextI -> Text -> Text
dropWord TextI
p Text
t
(Break (takeWord p t) (takeWord d u) (dropWord d u) s :) `fmap` go n
unsafeInterleaveIO $ go =<< IO.first bi
breaksRight :: Breaker a -> Text -> [Break a]
breaksRight :: forall a. Breaker a -> Text -> [Break a]
breaksRight (B BreakIterator a
b) Text
t = IO [Break a] -> [Break a]
forall a. IO a -> a
unsafePerformIO (IO [Break a] -> [Break a]) -> IO [Break a] -> [Break a]
forall a b. (a -> b) -> a -> b
$ do
bi <- BreakIterator a -> IO (BreakIterator a)
forall a. BreakIterator a -> IO (BreakIterator a)
IO.clone BreakIterator a
b
IO.setText bi t
let go TextI
p = do
mix <- BreakIterator a -> IO (Maybe TextI)
forall a. BreakIterator a -> IO (Maybe TextI)
IO.previous BreakIterator a
bi
case mix of
Maybe TextI
Nothing -> [Break a] -> IO [Break a]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just TextI
n -> do
s <- BreakIterator a -> IO a
forall a. BreakIterator a -> IO a
IO.getStatus BreakIterator a
bi
let d = TextI
pTextI -> TextI -> TextI
forall a. Num a => a -> a -> a
-TextI
n
u = TextI -> Text -> Text
dropWord TextI
n Text
t
(Break (takeWord n t) (takeWord d u) (dropWord d u) s :) `fmap` go n
unsafeInterleaveIO $ go =<< IO.last bi