{-# 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 = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. BreakIterator a -> Breaker a
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 = 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 = 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 = 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 = 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
forall a. Eq a => Break a -> Break a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Break a -> Break a -> Bool
$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
Eq, Int -> Break a -> ShowS
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
showList :: [Break a] -> ShowS
$cshowList :: forall a. Show a => [Break a] -> ShowS
show :: Break a -> String
$cshow :: forall a. Show a => Break a -> String
showsPrec :: Int -> Break a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Break a -> ShowS
Show)
instance (NFData a) => NFData (Break a) where
rnf :: Break a -> ()
rnf Break{a
Text
brkStatus :: a
brkSuffix :: Text
brkBreak :: Text
brkPrefix :: Text
brkStatus :: forall a. Break a -> a
brkSuffix :: forall a. Break a -> Text
brkBreak :: forall a. Break a -> Text
brkPrefix :: forall a. Break a -> Text
..} = 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 = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
BreakIterator a
bi <- forall a. BreakIterator a -> IO (BreakIterator a)
IO.clone BreakIterator a
b
forall a. BreakIterator a -> Text -> IO ()
IO.setText BreakIterator a
bi Text
t
let go :: TextI -> IO [Break a]
go TextI
p = do
Maybe TextI
mix <- forall a. BreakIterator a -> IO (Maybe TextI)
IO.next BreakIterator a
bi
case Maybe TextI
mix of
Maybe TextI
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return []
Just TextI
n -> do
a
s <- forall a. BreakIterator a -> IO a
IO.getStatus BreakIterator a
bi
let d :: TextI
d = TextI
nforall a. Num a => a -> a -> a
-TextI
p
u :: Text
u = TextI -> Text -> Text
dropWord TextI
p Text
t
(forall a. Text -> Text -> Text -> a -> Break a
Break (TextI -> Text -> Text
takeWord TextI
p Text
t) (TextI -> Text -> Text
takeWord TextI
d Text
u) (TextI -> Text -> Text
dropWord TextI
d Text
u) a
s forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` TextI -> IO [Break a]
go TextI
n
forall a. IO a -> IO a
unsafeInterleaveIO forall a b. (a -> b) -> a -> b
$ TextI -> IO [Break a]
go forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. BreakIterator a -> IO TextI
IO.first BreakIterator a
bi
breaksRight :: Breaker a -> Text -> [Break a]
breaksRight :: forall a. Breaker a -> Text -> [Break a]
breaksRight (B BreakIterator a
b) Text
t = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ do
BreakIterator a
bi <- forall a. BreakIterator a -> IO (BreakIterator a)
IO.clone BreakIterator a
b
forall a. BreakIterator a -> Text -> IO ()
IO.setText BreakIterator a
bi Text
t
let go :: TextI -> IO [Break a]
go TextI
p = do
Maybe TextI
mix <- forall a. BreakIterator a -> IO (Maybe TextI)
IO.previous BreakIterator a
bi
case Maybe TextI
mix of
Maybe TextI
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return []
Just TextI
n -> do
a
s <- forall a. BreakIterator a -> IO a
IO.getStatus BreakIterator a
bi
let d :: TextI
d = TextI
pforall a. Num a => a -> a -> a
-TextI
n
u :: Text
u = TextI -> Text -> Text
dropWord TextI
n Text
t
(forall a. Text -> Text -> Text -> a -> Break a
Break (TextI -> Text -> Text
takeWord TextI
n Text
t) (TextI -> Text -> Text
takeWord TextI
d Text
u) (TextI -> Text -> Text
dropWord TextI
d Text
u) a
s forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` TextI -> IO [Break a]
go TextI
n
forall a. IO a -> IO a
unsafeInterleaveIO forall a b. (a -> b) -> a -> b
$ TextI -> IO [Break a]
go forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. BreakIterator a -> IO TextI
IO.last BreakIterator a
bi