{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
module B9.Text
( Text,
LazyText,
ByteString,
LazyByteString,
Textual (..),
writeTextFile,
unsafeRenderToText,
unsafeParseFromText,
parseFromTextWithErrorMessage,
encodeAsUtf8LazyByteString,
)
where
import Control.Exception (displayException)
import Control.Monad.IO.Class
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as LazyByteString
import qualified Data.Text as Text
import Data.Text (Text)
import qualified Data.Text.Encoding as Text
import qualified Data.Text.IO as Text
import qualified Data.Text.Lazy as LazyText
import qualified Data.Text.Lazy.Encoding as LazyText
import GHC.Stack
type LazyByteString = LazyByteString.ByteString
type LazyText = LazyText.Text
class Textual a where
renderToText :: HasCallStack => a -> Either String Text
parseFromText :: HasCallStack => Text -> Either String a
instance Textual Text where
renderToText = Right
parseFromText = Right
instance Textual String where
renderToText = Right . Text.pack
parseFromText = Right . Text.unpack
instance Textual ByteString where
renderToText x = case Text.decodeUtf8' x of
Left u ->
Left
( "renderToText of the ByteString failed: "
++ displayException u
++ " "
++ show x
++ "\nat:\n"
++ prettyCallStack callStack
)
Right t -> Right t
parseFromText = Right . Text.encodeUtf8
instance Textual LazyByteString where
renderToText x = case LazyText.decodeUtf8' x of
Left u ->
Left
( "renderToText of the LazyByteString failed: "
++ displayException u
++ " "
++ show x
++ "\nat:\n"
++ prettyCallStack callStack
)
Right t -> Right (LazyText.toStrict t)
parseFromText = Right . LazyByteString.fromStrict . Text.encodeUtf8
writeTextFile :: (HasCallStack, MonadIO m) => FilePath -> Text -> m ()
writeTextFile f = liftIO . Text.writeFile f
unsafeRenderToText :: (Textual a, HasCallStack) => a -> Text
unsafeRenderToText = either error id . renderToText
unsafeParseFromText :: (Textual a, HasCallStack) => Text -> a
unsafeParseFromText = either error id . parseFromText
encodeAsUtf8LazyByteString :: HasCallStack => String -> LazyByteString
encodeAsUtf8LazyByteString =
LazyByteString.fromStrict . Text.encodeUtf8 . Text.pack
parseFromTextWithErrorMessage ::
(HasCallStack, Textual a) =>
String ->
Text ->
Either String a
parseFromTextWithErrorMessage errorMessage b = case parseFromText b of
Left e -> Left (unwords [errorMessage, e])
Right a -> Right a