{-# LINE 1 "Data/Text/ICU/Enumerator.hsc" #-}
{-# LANGUAGE EmptyDataDecls, BangPatterns, ForeignFunctionInterface, RecordWildCards #-}
module Data.Text.ICU.Enumerator
(next, toList, createEnumerator, Enumerator, UEnumerator,
) where
import Data.Int (Int32)
import Data.Text (Text)
import Data.Text.ICU.Error.Internal (UErrorCode, handleError)
import Data.Text.ICU.Internal (UChar, newICUPtr, fromUCharPtr)
import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Ptr (FunPtr, Ptr, nullPtr)
import Foreign.Storable (peek)
import Prelude hiding (last)
data UEnumerator
newtype Enumerator = Enumerator {Enumerator -> ForeignPtr UEnumerator
enumeratorToForeignPtr :: ForeignPtr UEnumerator}
createEnumerator :: IO (Ptr UEnumerator) -> IO Enumerator
createEnumerator :: IO (Ptr UEnumerator) -> IO Enumerator
createEnumerator = (ForeignPtr UEnumerator -> Enumerator)
-> FinalizerPtr UEnumerator
-> IO (Ptr UEnumerator)
-> IO Enumerator
forall a i.
(ForeignPtr a -> i) -> FinalizerPtr a -> IO (Ptr a) -> IO i
newICUPtr ForeignPtr UEnumerator -> Enumerator
Enumerator FinalizerPtr UEnumerator
uenum_close
next :: Enumerator -> IO (Maybe Text)
next :: Enumerator -> IO (Maybe Text)
next Enumerator
enum = ForeignPtr UEnumerator
-> (Ptr UEnumerator -> IO (Maybe Text)) -> IO (Maybe Text)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr (Enumerator -> ForeignPtr UEnumerator
enumeratorToForeignPtr Enumerator
enum) ((Ptr UEnumerator -> IO (Maybe Text)) -> IO (Maybe Text))
-> (Ptr UEnumerator -> IO (Maybe Text)) -> IO (Maybe Text)
forall a b. (a -> b) -> a -> b
$ \Ptr UEnumerator
enumPtr ->
(Ptr Int32 -> IO (Maybe Text)) -> IO (Maybe Text)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int32 -> IO (Maybe Text)) -> IO (Maybe Text))
-> (Ptr Int32 -> IO (Maybe Text)) -> IO (Maybe Text)
forall a b. (a -> b) -> a -> b
$ \Ptr Int32
lenPtr -> do
Ptr UChar
textPtr <- (Ptr UErrorCode -> IO (Ptr UChar)) -> IO (Ptr UChar)
forall a. (Ptr UErrorCode -> IO a) -> IO a
handleError ((Ptr UErrorCode -> IO (Ptr UChar)) -> IO (Ptr UChar))
-> (Ptr UErrorCode -> IO (Ptr UChar)) -> IO (Ptr UChar)
forall a b. (a -> b) -> a -> b
$ Ptr UEnumerator -> Ptr Int32 -> Ptr UErrorCode -> IO (Ptr UChar)
uenum_unext Ptr UEnumerator
enumPtr Ptr Int32
lenPtr
if Ptr UChar
textPtr Ptr UChar -> Ptr UChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr UChar
forall a. Ptr a
nullPtr
then Maybe Text -> IO (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing
else do
Int32
n <- Ptr Int32 -> IO Int32
forall a. Storable a => Ptr a -> IO a
peek Ptr Int32
lenPtr
Text
t <- Ptr UChar -> I16 -> IO Text
fromUCharPtr Ptr UChar
textPtr (Int32 -> I16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
n)
Maybe Text -> IO (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Text -> IO (Maybe Text)) -> Maybe Text -> IO (Maybe Text)
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t
toList :: Enumerator -> IO [Text]
toList :: Enumerator -> IO [Text]
toList Enumerator
enum = [Text] -> [Text]
forall a. [a] -> [a]
reverse ([Text] -> [Text]) -> IO [Text] -> IO [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text] -> IO [Text]
go []
where
go :: [Text] -> IO [Text]
go [Text]
l = do
Maybe Text
mx <- Enumerator -> IO (Maybe Text)
next Enumerator
enum
case Maybe Text
mx of
Maybe Text
Nothing -> [Text] -> IO [Text]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Text]
l
Just Text
x -> [Text] -> IO [Text]
go (Text
xText -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
l)
foreign import ccall unsafe "hs_text_icu.h &__hs_uenum_close" uenum_close
:: FunPtr (Ptr UEnumerator -> IO ())
foreign import ccall unsafe "hs_text_icu.h __hs_uenum_unext" uenum_unext
:: Ptr UEnumerator -> Ptr Int32 -> Ptr UErrorCode
-> IO (Ptr UChar)