{-# OPTIONS_GHC -Wno-redundant-constraints #-}
module FileSystem.UTF8
(
decodeUtf8,
decodeUtf8Lenient,
decodeUtf8ThrowM,
decodeUtf8Fail,
unsafeDecodeUtf8,
TEnc.encodeUtf8,
normalizeC,
NormalizationMode (..),
TNormalize.normalize,
glyphLength,
)
where
import Control.Category ((>>>))
import Control.Exception (Exception (displayException))
import Control.Monad.Catch (MonadThrow, throwM)
import Data.ByteString (ByteString)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.Encoding qualified as TEnc
import Data.Text.Encoding.Error (UnicodeException)
import Data.Text.Encoding.Error qualified as TEncError
import Data.Text.Normalize (NormalizationMode (NFC, NFD, NFKC, NFKD))
import Data.Text.Normalize qualified as TNormalize
import GHC.Stack (HasCallStack)
decodeUtf8 :: ByteString -> Either UnicodeException Text
decodeUtf8 :: ByteString -> Either UnicodeException Text
decodeUtf8 = ByteString -> Either UnicodeException Text
TEnc.decodeUtf8'
decodeUtf8Lenient :: ByteString -> Text
decodeUtf8Lenient :: ByteString -> Text
decodeUtf8Lenient = OnDecodeError -> ByteString -> Text
TEnc.decodeUtf8With OnDecodeError
TEncError.lenientDecode
decodeUtf8ThrowM ::
(HasCallStack, MonadThrow m) =>
ByteString ->
m Text
decodeUtf8ThrowM :: forall (m :: * -> *).
(HasCallStack, MonadThrow m) =>
ByteString -> m Text
decodeUtf8ThrowM =
ByteString -> Either UnicodeException Text
decodeUtf8 (ByteString -> Either UnicodeException Text)
-> (Either UnicodeException Text -> m Text) -> ByteString -> m Text
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> \case
Right Text
txt -> Text -> m Text
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
txt
Left UnicodeException
ex -> UnicodeException -> m Text
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM UnicodeException
ex
{-# INLINEABLE decodeUtf8ThrowM #-}
decodeUtf8Fail ::
(HasCallStack, MonadFail m) =>
ByteString ->
m Text
decodeUtf8Fail :: forall (m :: * -> *).
(HasCallStack, MonadFail m) =>
ByteString -> m Text
decodeUtf8Fail =
ByteString -> Either UnicodeException Text
decodeUtf8 (ByteString -> Either UnicodeException Text)
-> (Either UnicodeException Text -> m Text) -> ByteString -> m Text
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> \case
Right Text
txt -> Text -> m Text
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
txt
Left UnicodeException
ex -> String -> m Text
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> m Text) -> String -> m Text
forall a b. (a -> b) -> a -> b
$ UnicodeException -> String
forall e. Exception e => e -> String
displayException UnicodeException
ex
{-# INLINEABLE decodeUtf8Fail #-}
unsafeDecodeUtf8 ::
(HasCallStack) =>
ByteString ->
Text
unsafeDecodeUtf8 :: HasCallStack => ByteString -> Text
unsafeDecodeUtf8 =
ByteString -> Either UnicodeException Text
decodeUtf8 (ByteString -> Either UnicodeException Text)
-> (Either UnicodeException Text -> Text) -> ByteString -> Text
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> \case
Right Text
txt -> Text
txt
Left UnicodeException
ex -> String -> Text
forall a. HasCallStack => String -> a
error (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ UnicodeException -> String
forall e. Exception e => e -> String
displayException UnicodeException
ex
glyphLength :: Text -> Int
glyphLength :: Text -> Int
glyphLength = Text -> Int
T.length (Text -> Int) -> (Text -> Text) -> Text -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
normalizeC
normalizeC :: Text -> Text
normalizeC :: Text -> Text
normalizeC = NormalizationMode -> Text -> Text
TNormalize.normalize NormalizationMode
NFC