{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module RIO.Prelude.Display
( Utf8Builder (..)
, Display (..)
, displayShow
, utf8BuilderToText
, utf8BuilderToLazyText
, displayBytesUtf8
, writeFileUtf8Builder
) where
import Data.String (IsString (..))
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Builder as BB
import Data.ByteString.Builder (Builder)
import Data.Semigroup (Semigroup(..))
import Data.Text (Text)
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TL
import UnliftIO
import Data.Text.Encoding (decodeUtf8With, encodeUtf8Builder)
import Data.Text.Encoding.Error (lenientDecode)
import Data.Int
import Data.Word
import System.Process.Typed (ProcessConfig, setEnvInherit)
newtype Utf8Builder = Utf8Builder { Utf8Builder -> Builder
getUtf8Builder :: Builder }
deriving (b -> Utf8Builder -> Utf8Builder
NonEmpty Utf8Builder -> Utf8Builder
Utf8Builder -> Utf8Builder -> Utf8Builder
(Utf8Builder -> Utf8Builder -> Utf8Builder)
-> (NonEmpty Utf8Builder -> Utf8Builder)
-> (forall b. Integral b => b -> Utf8Builder -> Utf8Builder)
-> Semigroup Utf8Builder
forall b. Integral b => b -> Utf8Builder -> Utf8Builder
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> Utf8Builder -> Utf8Builder
$cstimes :: forall b. Integral b => b -> Utf8Builder -> Utf8Builder
sconcat :: NonEmpty Utf8Builder -> Utf8Builder
$csconcat :: NonEmpty Utf8Builder -> Utf8Builder
<> :: Utf8Builder -> Utf8Builder -> Utf8Builder
$c<> :: Utf8Builder -> Utf8Builder -> Utf8Builder
Semigroup)
instance Monoid Utf8Builder where
mempty :: Utf8Builder
mempty = Builder -> Utf8Builder
Utf8Builder Builder
forall a. Monoid a => a
mempty
{-# INLINE mempty #-}
mappend :: Utf8Builder -> Utf8Builder -> Utf8Builder
mappend = Utf8Builder -> Utf8Builder -> Utf8Builder
forall a. Semigroup a => a -> a -> a
(Data.Semigroup.<>)
{-# INLINE mappend #-}
mconcat :: [Utf8Builder] -> Utf8Builder
mconcat = (Utf8Builder -> Utf8Builder -> Utf8Builder)
-> Utf8Builder -> [Utf8Builder] -> Utf8Builder
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Utf8Builder -> Utf8Builder -> Utf8Builder
forall a. Monoid a => a -> a -> a
mappend Utf8Builder
forall a. Monoid a => a
mempty
{-# INLINE mconcat #-}
instance IsString Utf8Builder where
fromString :: String -> Utf8Builder
fromString = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (String -> Builder) -> String -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder
BB.stringUtf8
class Display a where
{-# MINIMAL display | textDisplay #-}
display :: a -> Utf8Builder
display = Text -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display (Text -> Utf8Builder) -> (a -> Text) -> a -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. Display a => a -> Text
textDisplay
textDisplay :: a -> Text
textDisplay = Utf8Builder -> Text
utf8BuilderToText (Utf8Builder -> Text) -> (a -> Utf8Builder) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display
instance Display Utf8Builder where
display :: Utf8Builder -> Utf8Builder
display = Utf8Builder -> Utf8Builder
forall a. a -> a
id
instance Display Text where
display :: Text -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Text -> Builder) -> Text -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Builder
encodeUtf8Builder
instance Display TL.Text where
display :: Text -> Utf8Builder
display = (Text -> Utf8Builder) -> [Text] -> Utf8Builder
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Text -> Utf8Builder
forall a. Display a => a -> Utf8Builder
display ([Text] -> Utf8Builder) -> (Text -> [Text]) -> Text -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
TL.toChunks
instance Display Char where
display :: Char -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Char -> Builder) -> Char -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Builder
BB.charUtf8
instance Display Integer where
display :: Integer -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Integer -> Builder) -> Integer -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Builder
BB.integerDec
instance Display Float where
display :: Float -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Float -> Builder) -> Float -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Builder
BB.floatDec
instance Display Double where
display :: Double -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Double -> Builder) -> Double -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Builder
BB.doubleDec
instance Display Int where
display :: Int -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder) -> (Int -> Builder) -> Int -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Builder
BB.intDec
instance Display Int8 where
display :: Int8 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Int8 -> Builder) -> Int8 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Builder
BB.int8Dec
instance Display Int16 where
display :: Int16 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Int16 -> Builder) -> Int16 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> Builder
BB.int16Dec
instance Display Int32 where
display :: Int32 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Int32 -> Builder) -> Int32 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Builder
BB.int32Dec
instance Display Int64 where
display :: Int64 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Int64 -> Builder) -> Int64 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Builder
BB.int64Dec
instance Display Word where
display :: Word -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Word -> Builder) -> Word -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> Builder
BB.wordDec
instance Display Word8 where
display :: Word8 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Word8 -> Builder) -> Word8 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Builder
BB.word8Dec
instance Display Word16 where
display :: Word16 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Word16 -> Builder) -> Word16 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> Builder
BB.word16Dec
instance Display Word32 where
display :: Word32 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Word32 -> Builder) -> Word32 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
BB.word32Dec
instance Display Word64 where
display :: Word64 -> Utf8Builder
display = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (Word64 -> Builder) -> Word64 -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
BB.word64Dec
instance Display SomeException where
display :: SomeException -> Utf8Builder
display = String -> Utf8Builder
forall a. IsString a => String -> a
fromString (String -> Utf8Builder)
-> (SomeException -> String) -> SomeException -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> String
forall e. Exception e => e -> String
displayException
instance Display IOException where
display :: IOException -> Utf8Builder
display = String -> Utf8Builder
forall a. IsString a => String -> a
fromString (String -> Utf8Builder)
-> (IOException -> String) -> IOException -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOException -> String
forall e. Exception e => e -> String
displayException
instance Display (ProcessConfig a b c) where
display :: ProcessConfig a b c -> Utf8Builder
display = ProcessConfig a b c -> Utf8Builder
forall a. Show a => a -> Utf8Builder
displayShow (ProcessConfig a b c -> Utf8Builder)
-> (ProcessConfig a b c -> ProcessConfig a b c)
-> ProcessConfig a b c
-> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProcessConfig a b c -> ProcessConfig a b c
forall stdin stdout stderr.
ProcessConfig stdin stdout stderr
-> ProcessConfig stdin stdout stderr
setEnvInherit
displayShow :: Show a => a -> Utf8Builder
displayShow :: a -> Utf8Builder
displayShow = String -> Utf8Builder
forall a. IsString a => String -> a
fromString (String -> Utf8Builder) -> (a -> String) -> a -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
displayBytesUtf8 :: ByteString -> Utf8Builder
displayBytesUtf8 :: ByteString -> Utf8Builder
displayBytesUtf8 = Builder -> Utf8Builder
Utf8Builder (Builder -> Utf8Builder)
-> (ByteString -> Builder) -> ByteString -> Utf8Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Builder
BB.byteString
utf8BuilderToText :: Utf8Builder -> Text
utf8BuilderToText :: Utf8Builder -> Text
utf8BuilderToText =
OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode (ByteString -> Text)
-> (Utf8Builder -> ByteString) -> Utf8Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
BL.toStrict (ByteString -> ByteString)
-> (Utf8Builder -> ByteString) -> Utf8Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
BB.toLazyByteString (Builder -> ByteString)
-> (Utf8Builder -> Builder) -> Utf8Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Utf8Builder -> Builder
getUtf8Builder
utf8BuilderToLazyText :: Utf8Builder -> TL.Text
utf8BuilderToLazyText :: Utf8Builder -> Text
utf8BuilderToLazyText =
OnDecodeError -> ByteString -> Text
TL.decodeUtf8With OnDecodeError
lenientDecode (ByteString -> Text)
-> (Utf8Builder -> ByteString) -> Utf8Builder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> ByteString
BB.toLazyByteString (Builder -> ByteString)
-> (Utf8Builder -> Builder) -> Utf8Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Utf8Builder -> Builder
getUtf8Builder
writeFileUtf8Builder :: MonadIO m => FilePath -> Utf8Builder -> m ()
writeFileUtf8Builder :: String -> Utf8Builder -> m ()
writeFileUtf8Builder String
fp (Utf8Builder Builder
builder) =
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> IOMode -> (Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> IOMode -> (Handle -> m a) -> m a
withBinaryFile String
fp IOMode
WriteMode ((Handle -> IO ()) -> IO ()) -> (Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Handle
h -> Handle -> Builder -> IO ()
BB.hPutBuilder Handle
h Builder
builder