{-# LANGUAGE TypeSynonymInstances,FlexibleInstances #-}
module B9.Text
( Text
, LazyText
, ByteString
, LazyByteString
, Textual(..)
, writeTextFile
, unsafeRenderToText
, unsafeParseFromText
, parseFromTextWithErrorMessage
, encodeAsUtf8LazyByteString
)
where
import Data.ByteString ( ByteString )
import Control.Exception ( displayException )
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 Control.Monad.IO.Class
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