{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DefaultSignatures          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE TypeOperators              #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE DeriveAnyClass             #-}

{-|
Module      : Z.Data.Text.Builder
Description : UTF8 compatible builders.
Copyright   : (c) Dong Han, 2017-2019
License     : BSD
Maintainer  : winterland1989@gmail.com
Stability   : experimental
Portability : non-portable

Base on UTF8 compatible textual builders from 'Z.Data.Builder', we provide a newtype wrapper
'TextBuilder' which can be directly used to build 'Text'.

We also provide faster alternative to 'Show' class, i.e. 'ToText', which also provides 'Generic'
based instances deriving.

-}

module Z.Data.Text.Builder
  ( -- * ToText class
  ToText(..), toText, toBuilder, toBytes, toString
  -- * Str newtype
  , Str(..)
  -- * Textual Builder
  , TextBuilder
  , getBuilder
  , unsafeFromBuilder
  , buildText
  -- * Basic UTF8 builders
  , stringUTF8, charUTF8, string7, char7, text
  -- * Numeric builders
  -- ** Integral type formatting
  , B.IFormat(..)
  , B.defaultIFormat
  , B.Padding(..)
  , int
  , intWith
  , integer
  -- ** Fixded size hexidecimal formatting
  , hex, heX
  -- ** IEEE float formating
  , B.FFormat(..)
  , double
  , doubleWith
  , float
  , floatWith
  , scientific
  , scientificWith
  -- * Builder helpers
  , paren, parenWhen, curly, square, angle, quotes, squotes, colon, comma, intercalateVec, intercalateList
  ) where

import           Control.Monad
import qualified Data.Scientific          as Sci
import           Data.String
import           Data.Bits
import           Data.Data                (Data(..))
import           Data.Fixed
import           Data.Functor.Compose
import           Data.Functor.Const
import           Data.Functor.Identity
import           Data.Functor.Product
import           Data.Functor.Sum
import           Data.Int
import           Data.List.NonEmpty           (NonEmpty (..))
import qualified Data.Monoid                  as Monoid
import           Data.Proxy                   (Proxy (..))
import           Data.Ratio                   (Ratio, numerator, denominator)
import           Data.Tagged                  (Tagged (..))
import           Data.Word
import qualified Data.Semigroup               as Semigroup
import           Data.Typeable
import           GHC.Natural
import           GHC.Generics
import           Data.Version
import           Data.Primitive.Types
import qualified Z.Data.Builder         as B
import qualified Z.Data.Text.Base       as T
import           Z.Data.Text.Base       (Text(..))
import qualified Z.Data.Vector.Base     as V
import           Text.Read                (Read(..))
import           Test.QuickCheck.Arbitrary (Arbitrary(..), CoArbitrary(..))

-- | Buidlers which guarantee UTF-8 encoding, thus can be used to build
-- text directly.
--
-- Notes on 'IsString' instance: It's recommended to use 'IsString' instance, there's a rewrite rule to
-- turn encoding loop into a memcpy, which is much faster (the same rule also apply to 'stringUTF8').
-- Different from @Builder ()@, @TextBuilder ()@'s 'IsString' instance will give you desired UTF8 guarantees:
--
-- * @\NUL@ will be written directly as @\x00@.
--
-- * @\xD800@ ~ @\xDFFF@ will be replaced by replacement char.
--
newtype TextBuilder a = TextBuilder { TextBuilder a -> Builder a
getBuilder :: B.Builder a }
    deriving newtype (a -> TextBuilder b -> TextBuilder a
(a -> b) -> TextBuilder a -> TextBuilder b
(forall a b. (a -> b) -> TextBuilder a -> TextBuilder b)
-> (forall a b. a -> TextBuilder b -> TextBuilder a)
-> Functor TextBuilder
forall a b. a -> TextBuilder b -> TextBuilder a
forall a b. (a -> b) -> TextBuilder a -> TextBuilder b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> TextBuilder b -> TextBuilder a
$c<$ :: forall a b. a -> TextBuilder b -> TextBuilder a
fmap :: (a -> b) -> TextBuilder a -> TextBuilder b
$cfmap :: forall a b. (a -> b) -> TextBuilder a -> TextBuilder b
Functor, Functor TextBuilder
a -> TextBuilder a
Functor TextBuilder
-> (forall a. a -> TextBuilder a)
-> (forall a b.
    TextBuilder (a -> b) -> TextBuilder a -> TextBuilder b)
-> (forall a b c.
    (a -> b -> c) -> TextBuilder a -> TextBuilder b -> TextBuilder c)
-> (forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b)
-> (forall a b. TextBuilder a -> TextBuilder b -> TextBuilder a)
-> Applicative TextBuilder
TextBuilder a -> TextBuilder b -> TextBuilder b
TextBuilder a -> TextBuilder b -> TextBuilder a
TextBuilder (a -> b) -> TextBuilder a -> TextBuilder b
(a -> b -> c) -> TextBuilder a -> TextBuilder b -> TextBuilder c
forall a. a -> TextBuilder a
forall a b. TextBuilder a -> TextBuilder b -> TextBuilder a
forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b
forall a b. TextBuilder (a -> b) -> TextBuilder a -> TextBuilder b
forall a b c.
(a -> b -> c) -> TextBuilder a -> TextBuilder b -> TextBuilder c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: TextBuilder a -> TextBuilder b -> TextBuilder a
$c<* :: forall a b. TextBuilder a -> TextBuilder b -> TextBuilder a
*> :: TextBuilder a -> TextBuilder b -> TextBuilder b
$c*> :: forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b
liftA2 :: (a -> b -> c) -> TextBuilder a -> TextBuilder b -> TextBuilder c
$cliftA2 :: forall a b c.
(a -> b -> c) -> TextBuilder a -> TextBuilder b -> TextBuilder c
<*> :: TextBuilder (a -> b) -> TextBuilder a -> TextBuilder b
$c<*> :: forall a b. TextBuilder (a -> b) -> TextBuilder a -> TextBuilder b
pure :: a -> TextBuilder a
$cpure :: forall a. a -> TextBuilder a
$cp1Applicative :: Functor TextBuilder
Applicative, Applicative TextBuilder
a -> TextBuilder a
Applicative TextBuilder
-> (forall a b.
    TextBuilder a -> (a -> TextBuilder b) -> TextBuilder b)
-> (forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b)
-> (forall a. a -> TextBuilder a)
-> Monad TextBuilder
TextBuilder a -> (a -> TextBuilder b) -> TextBuilder b
TextBuilder a -> TextBuilder b -> TextBuilder b
forall a. a -> TextBuilder a
forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b
forall a b. TextBuilder a -> (a -> TextBuilder b) -> TextBuilder b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> TextBuilder a
$creturn :: forall a. a -> TextBuilder a
>> :: TextBuilder a -> TextBuilder b -> TextBuilder b
$c>> :: forall a b. TextBuilder a -> TextBuilder b -> TextBuilder b
>>= :: TextBuilder a -> (a -> TextBuilder b) -> TextBuilder b
$c>>= :: forall a b. TextBuilder a -> (a -> TextBuilder b) -> TextBuilder b
$cp1Monad :: Applicative TextBuilder
Monad)

deriving newtype instance Semigroup (TextBuilder ())
deriving newtype instance Monoid (TextBuilder ())

instance (a ~ ()) => IsString (TextBuilder a) where
    {-# INLINE fromString #-}
    fromString :: String -> TextBuilder a
fromString = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (String -> Builder ()) -> String -> TextBuilder ()
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Builder ()
B.stringUTF8

instance Arbitrary (TextBuilder ()) where
    arbitrary :: Gen (TextBuilder ())
arbitrary = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Text -> Builder ()) -> Text -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Builder ()
B.text (Text -> TextBuilder ()) -> Gen Text -> Gen (TextBuilder ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Text
forall a. Arbitrary a => Gen a
arbitrary
    shrink :: TextBuilder () -> [TextBuilder ()]
shrink TextBuilder ()
b = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Text -> Builder ()) -> Text -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Builder ()
B.text (Text -> TextBuilder ()) -> [Text] -> [TextBuilder ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [Text]
forall a. Arbitrary a => a -> [a]
shrink (TextBuilder () -> Text
forall a. TextBuilder a -> Text
buildText TextBuilder ()
b)

instance CoArbitrary (TextBuilder ()) where
    coarbitrary :: TextBuilder () -> Gen b -> Gen b
coarbitrary = Text -> Gen b -> Gen b
forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary (Text -> Gen b -> Gen b)
-> (TextBuilder () -> Text) -> TextBuilder () -> Gen b -> Gen b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder () -> Text
forall a. TextBuilder a -> Text
buildText

instance Show (TextBuilder a) where
    show :: TextBuilder a -> String
show = Text -> String
forall a. Show a => a -> String
show (Text -> String)
-> (TextBuilder a -> Text) -> TextBuilder a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder a -> Text
forall a. TextBuilder a -> Text
buildText

instance ToText (TextBuilder a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> TextBuilder a -> TextBuilder ()
toTextBuilder Int
_ TextBuilder a
b = TextBuilder () -> TextBuilder ()
quotes (TextBuilder a -> TextBuilder ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void TextBuilder a
b)

-- | Build a 'Text' using 'TextBuilder', which provide UTF-8 encoding guarantee.
buildText :: TextBuilder a -> Text
{-# INLINE buildText #-}
buildText :: TextBuilder a -> Text
buildText = Bytes -> Text
Text (Bytes -> Text)
-> (TextBuilder a -> Bytes) -> TextBuilder a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder a -> Bytes
forall a. Builder a -> Bytes
B.buildBytes (Builder a -> Bytes)
-> (TextBuilder a -> Builder a) -> TextBuilder a -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder a -> Builder a
forall a. TextBuilder a -> Builder a
getBuilder

-- | Unsafely turn a 'B.Builder' into 'TextBuilder', thus it's user's responsibility to
-- ensure only UTF-8 complied bytes are written.
unsafeFromBuilder :: B.Builder a -> TextBuilder a
{-# INLINE unsafeFromBuilder #-}
unsafeFromBuilder :: Builder a -> TextBuilder a
unsafeFromBuilder = Builder a -> TextBuilder a
forall a. Builder a -> TextBuilder a
TextBuilder

--------------------------------------------------------------------------------

-- | Turn 'String' into 'TextBuilder' with UTF8 encoding
--
-- Illegal codepoints will be written as 'T.replacementChar's. This function will be rewritten into a memcpy if possible, (running a fast UTF-8 validation at runtime first).
stringUTF8 :: String -> TextBuilder ()
{-# INLINE stringUTF8 #-}
stringUTF8 :: String -> TextBuilder ()
stringUTF8 = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (String -> Builder ()) -> String -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.stringUTF8

-- | Turn 'Char' into 'TextBuilder' with UTF8 encoding
--
-- Illegal codepoints will be written as 'T.replacementChar's.
charUTF8 :: Char -> TextBuilder ()
{-# INLINE charUTF8 #-}
charUTF8 :: Char -> TextBuilder ()
charUTF8 = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Char -> Builder ()) -> Char -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Builder ()
B.charUTF8

-- | Turn 'String' into 'TextBuilder' with ASCII7 encoding
--
-- Codepoints beyond @'\x7F'@ will be chopped.
string7 :: String -> TextBuilder ()
{-# INLINE string7 #-}
string7 :: String -> TextBuilder ()
string7 = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (String -> Builder ()) -> String -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.string7

-- | Turn 'Char' into 'TextBuilder' with ASCII7 encoding
--
-- Codepoints beyond @'\x7F'@ will be chopped.
char7 :: Char -> TextBuilder ()
{-# INLINE char7 #-}
char7 :: Char -> TextBuilder ()
char7 = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Char -> Builder ()) -> Char -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Builder ()
B.char7

-- | Write UTF8 encoded 'T.Text' using 'Builder'.
--
-- Note, if you're trying to write string literals builders,
-- please open 'OverloadedStrings' and use 'Builder's 'IsString' instance,
-- it will be rewritten into a memcpy.
text :: T.Text -> TextBuilder ()
{-# INLINE text #-}
text :: Text -> TextBuilder ()
text = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Text -> Builder ()) -> Text -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Builder ()
B.text

--------------------------------------------------------------------------------

-- | @int = intWith defaultIFormat@
int :: (Integral a, Bounded a) => a -> TextBuilder ()
{-# INLINE int #-}
int :: a -> TextBuilder ()
int = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (a -> Builder ()) -> a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder ()
forall a. (Integral a, Bounded a) => a -> Builder ()
B.int

-- | Format a 'Bounded' 'Integral' type like @Int@ or @Word16@ into decimal ascii digits.
intWith :: (Integral a, Bounded a)
        => B.IFormat
        -> a
        -> TextBuilder ()
{-# INLINE intWith #-}
intWith :: IFormat -> a -> TextBuilder ()
intWith IFormat
fmt a
x = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ IFormat -> a -> Builder ()
forall a. (Integral a, Bounded a) => IFormat -> a -> Builder ()
B.intWith IFormat
fmt a
x

-- | Format a 'Integer' into decimal ascii digits.
integer :: Integer -> TextBuilder ()
{-# INLINE integer #-}
integer :: Integer -> TextBuilder ()
integer = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Integer -> Builder ()) -> Integer -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Builder ()
B.integer

-- | Format a 'FiniteBits' 'Integral' type into hex nibbles.
hex :: (FiniteBits a, Integral a) => a -> TextBuilder ()
{-# INLINE hex #-}
hex :: a -> TextBuilder ()
hex = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (a -> Builder ()) -> a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder ()
forall a. (FiniteBits a, Integral a) => a -> Builder ()
B.hex

-- | The UPPERCASED version of 'hex'.
heX :: (FiniteBits a, Integral a) => a -> TextBuilder ()
{-# INLINE heX #-}
heX :: a -> TextBuilder ()
heX = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (a -> Builder ()) -> a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder ()
forall a. (FiniteBits a, Integral a) => a -> Builder ()
B.heX

-- | Decimal encoding of an IEEE 'Float'.
--
-- Using standard decimal notation for arguments whose absolute value lies
-- between @0.1@ and @9,999,999@, and scientific notation otherwise.
float :: Float -> TextBuilder ()
{-# INLINE float #-}
float :: Float -> TextBuilder ()
float = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Float -> Builder ()) -> Float -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Builder ()
B.float

-- | Format single-precision float using drisu3 with dragon4 fallback.
floatWith :: B.FFormat
          -> Maybe Int  -- ^ Number of decimal places to render.
          -> Float
          -> TextBuilder ()
{-# INLINE floatWith #-}
floatWith :: FFormat -> Maybe Int -> Float -> TextBuilder ()
floatWith FFormat
fmt Maybe Int
ds Float
x = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (FFormat -> Maybe Int -> Float -> Builder ()
B.floatWith FFormat
fmt Maybe Int
ds Float
x)


-- | Decimal encoding of an IEEE 'Double'.
--
-- Using standard decimal notation for arguments whose absolute value lies
-- between @0.1@ and @9,999,999@, and scientific notation otherwise.
double :: Double -> TextBuilder ()
{-# INLINE double #-}
double :: Double -> TextBuilder ()
double = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Double -> Builder ()) -> Double -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Builder ()
B.double

-- | Format double-precision float using drisu3 with dragon4 fallback.
doubleWith :: B.FFormat
           -> Maybe Int  -- ^ Number of decimal places to render.
           -> Double
           -> TextBuilder ()
{-# INLINE doubleWith #-}
doubleWith :: FFormat -> Maybe Int -> Double -> TextBuilder ()
doubleWith FFormat
fmt Maybe Int
ds Double
x = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (FFormat -> Maybe Int -> Double -> Builder ()
B.doubleWith FFormat
fmt Maybe Int
ds Double
x)


-- | A @Builder@ which renders a scientific number to full
-- precision, using standard decimal notation for arguments whose
-- absolute value lies between @0.1@ and @9,999,999@, and scientific
-- notation otherwise.
scientific :: Sci.Scientific -> TextBuilder ()
{-# INLINE scientific #-}
scientific :: Scientific -> TextBuilder ()
scientific = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Scientific -> Builder ()) -> Scientific -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> Builder ()
B.scientific

-- | Like 'scientific' but provides rendering options.
scientificWith :: B.FFormat
               -> Maybe Int  -- ^ Number of decimal places to render.
               -> Sci.Scientific
               -> TextBuilder ()
{-# INLINE scientificWith #-}
scientificWith :: FFormat -> Maybe Int -> Scientific -> TextBuilder ()
scientificWith FFormat
fmt Maybe Int
ds Scientific
x = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (FFormat -> Maybe Int -> Scientific -> Builder ()
B.scientificWith FFormat
fmt Maybe Int
ds Scientific
x)

--------------------------------------------------------------------------------

-- | add @(...)@ to original builder.
paren :: TextBuilder () -> TextBuilder ()
{-# INLINE paren #-}
paren :: TextBuilder () -> TextBuilder ()
paren (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.paren Builder ()
b)

-- | Add "(..)" around builders when condition is met, otherwise add nothing.
--
-- This is useful when defining 'ToText' instances.
parenWhen :: Bool -> TextBuilder () -> TextBuilder ()
{-# INLINE parenWhen #-}
parenWhen :: Bool -> TextBuilder () -> TextBuilder ()
parenWhen Bool
True TextBuilder ()
b = TextBuilder () -> TextBuilder ()
paren TextBuilder ()
b
parenWhen Bool
_    TextBuilder ()
b = TextBuilder ()
b

-- | add @{...}@ to original builder.
curly :: TextBuilder () -> TextBuilder ()
{-# INLINE curly #-}
curly :: TextBuilder () -> TextBuilder ()
curly (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.curly Builder ()
b)

-- | add @[...]@ to original builder.
square :: TextBuilder () -> TextBuilder ()
{-# INLINE square #-}
square :: TextBuilder () -> TextBuilder ()
square (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.square Builder ()
b)

-- | add @<...>@ to original builder.
angle :: TextBuilder () -> TextBuilder ()
{-# INLINE angle #-}
angle :: TextBuilder () -> TextBuilder ()
angle (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.angle Builder ()
b)

-- | add @"..."@ to original builder.
quotes :: TextBuilder () -> TextBuilder ()
{-# INLINE quotes #-}
quotes :: TextBuilder () -> TextBuilder ()
quotes (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.quotes Builder ()
b)

-- | add @'...'@ to original builder.
squotes :: TextBuilder () -> TextBuilder ()
{-# INLINE squotes #-}
squotes :: TextBuilder () -> TextBuilder ()
squotes (TextBuilder Builder ()
b) = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> Builder ()
B.squotes Builder ()
b)

-- | write an ASCII @:@
colon ::  TextBuilder ()
{-# INLINE colon #-}
colon :: TextBuilder ()
colon = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
B.colon

-- | write an ASCII @,@
comma ::  TextBuilder ()
{-# INLINE comma #-}
comma :: TextBuilder ()
comma = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
B.comma

-- | Use separator to connect a vector of builders.
intercalateVec :: (V.Vec v a)
               => TextBuilder ()            -- ^ the seperator
               -> (a -> TextBuilder ())     -- ^ value formatter
               -> v a                       -- ^ value list
               ->  TextBuilder ()
{-# INLINE intercalateVec #-}
intercalateVec :: TextBuilder () -> (a -> TextBuilder ()) -> v a -> TextBuilder ()
intercalateVec (TextBuilder Builder ()
s) a -> TextBuilder ()
f = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (v a -> Builder ()) -> v a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder () -> (a -> Builder ()) -> v a -> Builder ()
forall (v :: * -> *) a.
Vec v a =>
Builder () -> (a -> Builder ()) -> v a -> Builder ()
B.intercalateVec Builder ()
s (TextBuilder () -> Builder ()
forall a. TextBuilder a -> Builder a
getBuilder (TextBuilder () -> Builder ())
-> (a -> TextBuilder ()) -> a -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> TextBuilder ()
f)

-- | Use separator to connect a list of builders.
intercalateList :: TextBuilder ()           -- ^ the seperator
                -> (a -> TextBuilder ())    -- ^ value formatter
                -> [a]                      -- ^ value vector
                -> TextBuilder ()
{-# INLINE intercalateList #-}
intercalateList :: TextBuilder () -> (a -> TextBuilder ()) -> [a] -> TextBuilder ()
intercalateList (TextBuilder Builder ()
s) a -> TextBuilder ()
f = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> ([a] -> Builder ()) -> [a] -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder () -> (a -> Builder ()) -> [a] -> Builder ()
forall a. Builder () -> (a -> Builder ()) -> [a] -> Builder ()
B.intercalateList Builder ()
s (TextBuilder () -> Builder ()
forall a. TextBuilder a -> Builder a
getBuilder (TextBuilder () -> Builder ())
-> (a -> TextBuilder ()) -> a -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> TextBuilder ()
f)

--------------------------------------------------------------------------------
-- | Newtype wrapper for @[Char]@ to provide textual instances.
--
-- To encourage using 'Text' as the textual representation, we didn't provide special
-- treatment to differentiate instances between @[a]@ and @[Char]@ in various places.
-- This newtype is therefore to provide instances similar to @T.Text@, in case you really
-- need to wrap a 'String'.
newtype Str = Str { Str -> String
chrs :: [Char] } deriving stock (Str -> Str -> Bool
(Str -> Str -> Bool) -> (Str -> Str -> Bool) -> Eq Str
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Str -> Str -> Bool
$c/= :: Str -> Str -> Bool
== :: Str -> Str -> Bool
$c== :: Str -> Str -> Bool
Eq, Eq Str
Eq Str
-> (Str -> Str -> Ordering)
-> (Str -> Str -> Bool)
-> (Str -> Str -> Bool)
-> (Str -> Str -> Bool)
-> (Str -> Str -> Bool)
-> (Str -> Str -> Str)
-> (Str -> Str -> Str)
-> Ord Str
Str -> Str -> Bool
Str -> Str -> Ordering
Str -> Str -> Str
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Str -> Str -> Str
$cmin :: Str -> Str -> Str
max :: Str -> Str -> Str
$cmax :: Str -> Str -> Str
>= :: Str -> Str -> Bool
$c>= :: Str -> Str -> Bool
> :: Str -> Str -> Bool
$c> :: Str -> Str -> Bool
<= :: Str -> Str -> Bool
$c<= :: Str -> Str -> Bool
< :: Str -> Str -> Bool
$c< :: Str -> Str -> Bool
compare :: Str -> Str -> Ordering
$ccompare :: Str -> Str -> Ordering
$cp1Ord :: Eq Str
Ord, Typeable Str
DataType
Constr
Typeable Str
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Str -> c Str)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Str)
-> (Str -> Constr)
-> (Str -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Str))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Str))
-> ((forall b. Data b => b -> b) -> Str -> Str)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r)
-> (forall u. (forall d. Data d => d -> u) -> Str -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Str -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Str -> m Str)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Str -> m Str)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Str -> m Str)
-> Data Str
Str -> DataType
Str -> Constr
(forall b. Data b => b -> b) -> Str -> Str
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Str -> c Str
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Str
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Str -> u
forall u. (forall d. Data d => d -> u) -> Str -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Str -> m Str
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Str -> m Str
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Str
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Str -> c Str
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Str)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Str)
$cStr :: Constr
$tStr :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Str -> m Str
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Str -> m Str
gmapMp :: (forall d. Data d => d -> m d) -> Str -> m Str
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Str -> m Str
gmapM :: (forall d. Data d => d -> m d) -> Str -> m Str
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Str -> m Str
gmapQi :: Int -> (forall d. Data d => d -> u) -> Str -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Str -> u
gmapQ :: (forall d. Data d => d -> u) -> Str -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Str -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Str -> r
gmapT :: (forall b. Data b => b -> b) -> Str -> Str
$cgmapT :: (forall b. Data b => b -> b) -> Str -> Str
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Str)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Str)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Str)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Str)
dataTypeOf :: Str -> DataType
$cdataTypeOf :: Str -> DataType
toConstr :: Str -> Constr
$ctoConstr :: Str -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Str
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Str
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Str -> c Str
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Str -> c Str
$cp1Data :: Typeable Str
Data, Typeable, (forall x. Str -> Rep Str x)
-> (forall x. Rep Str x -> Str) -> Generic Str
forall x. Rep Str x -> Str
forall x. Str -> Rep Str x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Str x -> Str
$cfrom :: forall x. Str -> Rep Str x
Generic)

instance Show Str where show :: Str -> String
show = ShowS
forall a. Show a => a -> String
show ShowS -> (Str -> String) -> Str -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Str -> String
chrs
instance Read Str where readPrec :: ReadPrec Str
readPrec = String -> Str
Str (String -> Str) -> ReadPrec String -> ReadPrec Str
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadPrec String
forall a. Read a => ReadPrec a
readPrec

instance ToText Str where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Str -> TextBuilder ()
toTextBuilder Int
_ = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Str -> Builder ()) -> Str -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.string8 (String -> Builder ()) -> (Str -> String) -> Str -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Str -> String
forall a. Show a => a -> String
show

--------------------------------------------------------------------------------
-- Data types
--
-- | A class similar to 'Show', serving the purpose that quickly convert a data type
-- to a 'Text' value.
class ToText a where
    toTextBuilder :: Int -> a  -> TextBuilder ()
    default toTextBuilder :: (Generic a, GToText (Rep a)) => Int -> a -> TextBuilder ()
    toTextBuilder Int
p = Int -> Rep a Any -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
p (Rep a Any -> TextBuilder ())
-> (a -> Rep a Any) -> a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Rep a Any
forall a x. Generic a => a -> Rep a x
from

class GToText f where
    gToTextBuilder :: Int -> f a -> TextBuilder ()


class GFieldToText f where
    gFieldToTextBuilder :: B.Builder () -> Int -> f a -> B.Builder ()

instance (GFieldToText a, GFieldToText b) => GFieldToText (a :*: b) where
    {-# INLINE gFieldToTextBuilder #-}
    gFieldToTextBuilder :: Builder () -> Int -> (:*:) a b a -> Builder ()
gFieldToTextBuilder Builder ()
sep Int
p (a a
a :*: b a
b) =
        Builder () -> Int -> a a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder Builder ()
sep Int
p a a
a Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Builder ()
sep Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Builder () -> Int -> b a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder Builder ()
sep Int
p b a
b

instance (GToText f) => GFieldToText (S1 (MetaSel Nothing u ss ds) f) where
    {-# INLINE gFieldToTextBuilder #-}
    gFieldToTextBuilder :: Builder ()
-> Int -> S1 ('MetaSel 'Nothing u ss ds) f a -> Builder ()
gFieldToTextBuilder Builder ()
_ Int
p (M1 f a
x) = TextBuilder () -> Builder ()
forall a. TextBuilder a -> Builder a
getBuilder (Int -> f a -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
p f a
x)

instance (GToText f, Selector (MetaSel (Just l) u ss ds)) => GFieldToText (S1 (MetaSel (Just l) u ss ds) f) where
    {-# INLINE gFieldToTextBuilder #-}
    gFieldToTextBuilder :: Builder ()
-> Int -> S1 ('MetaSel ('Just l) u ss ds) f a -> Builder ()
gFieldToTextBuilder Builder ()
_ Int
_ m1 :: S1 ('MetaSel ('Just l) u ss ds) f a
m1@(M1 f a
x) =
        String -> Builder ()
B.stringModifiedUTF8 (S1 ('MetaSel ('Just l) u ss ds) f a -> String
forall k (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
selName S1 ('MetaSel ('Just l) u ss ds) f a
m1) Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Builder ()
" = " Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder () -> Builder ()
forall a. TextBuilder a -> Builder a
getBuilder (Int -> f a -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
0 f a
x)

instance GToText V1 where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> V1 a -> TextBuilder ()
gToTextBuilder Int
_ = String -> V1 a -> TextBuilder ()
forall a. HasCallStack => String -> a
error String
"Z.Data.TextBuilder: empty data type"

instance (GToText f, GToText g) => GToText (f :+: g) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> (:+:) f g a -> TextBuilder ()
gToTextBuilder Int
p (L1 f a
x) = Int -> f a -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
p f a
x
    gToTextBuilder Int
p (R1 g a
x) = Int -> g a -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
p g a
x

-- | Constructor without payload, convert to String
instance (Constructor c) => GToText (C1 c U1) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> C1 c U1 a -> TextBuilder ()
gToTextBuilder Int
_ C1 c U1 a
m1 =
        Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (String -> Builder ()) -> String -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.stringModifiedUTF8 (String -> TextBuilder ()) -> String -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ C1 c U1 a -> String
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName C1 c U1 a
m1

-- | Constructor with payloads
instance (GFieldToText (S1 sc f), Constructor c) => GToText (C1 c (S1 sc f)) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> C1 c (S1 sc f) a -> TextBuilder ()
gToTextBuilder Int
p m1 :: C1 c (S1 sc f) a
m1@(M1 S1 sc f a
x) =
        Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do
            String -> Builder ()
B.stringModifiedUTF8 (String -> Builder ()) -> String -> Builder ()
forall a b. (a -> b) -> a -> b
$ C1 c (S1 sc f) a -> String
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName C1 c (S1 sc f) a
m1
            Char -> Builder ()
B.char8 Char
' '
            if C1 c (S1 sc f) a -> Bool
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> Bool
conIsRecord C1 c (S1 sc f) a
m1
            then Builder () -> Builder ()
B.curly (Builder () -> Builder ()) -> Builder () -> Builder ()
forall a b. (a -> b) -> a -> b
$ Builder () -> Int -> S1 sc f a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder (Char -> Builder ()
B.char7 Char
',' Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Builder ()
B.char7 Char
' ') Int
p S1 sc f a
x
            else Builder () -> Int -> S1 sc f a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder (Char -> Builder ()
B.char7 Char
' ') Int
11 S1 sc f a
x

instance (GFieldToText (a :*: b), Constructor c) => GToText (C1 c (a :*: b)) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> C1 c (a :*: b) a -> TextBuilder ()
gToTextBuilder Int
p m1 :: C1 c (a :*: b) a
m1@(M1 (:*:) a b a
x) =
        case C1 c (a :*: b) a -> Fixity
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> Fixity
conFixity C1 c (a :*: b) a
m1 of
            Fixity
Prefix -> Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do
                String -> Builder ()
B.stringModifiedUTF8 (String -> Builder ()) -> String -> Builder ()
forall a b. (a -> b) -> a -> b
$ C1 c (a :*: b) a -> String
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName C1 c (a :*: b) a
m1
                Char -> Builder ()
B.char8 Char
' '
                if C1 c (a :*: b) a -> Bool
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> Bool
conIsRecord C1 c (a :*: b) a
m1
                then Builder () -> Builder ()
B.curly (Builder () -> Builder ()) -> Builder () -> Builder ()
forall a b. (a -> b) -> a -> b
$ Builder () -> Int -> (:*:) a b a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder (Char -> Builder ()
B.char7 Char
',' Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Builder ()
B.char7 Char
' ') Int
p (:*:) a b a
x
                else Builder () -> Int -> (:*:) a b a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder (Char -> Builder ()
B.char7 Char
' ') Int
11 (:*:) a b a
x
            Infix Associativity
_ Int
p' -> Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
p') (TextBuilder () -> TextBuilder ())
-> (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ()) -> Builder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do
                Builder () -> Int -> (:*:) a b a -> Builder ()
forall (f :: * -> *) a.
GFieldToText f =>
Builder () -> Int -> f a -> Builder ()
gFieldToTextBuilder
                    (Char -> Builder ()
B.char8 Char
' ' Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> Builder ()
B.stringModifiedUTF8 (C1 c (a :*: b) a -> String
forall k (c :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Constructor c =>
t c f a -> String
conName C1 c (a :*: b) a
m1) Builder () -> Builder () -> Builder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Builder ()
B.char8 Char
' ') (Int
p'Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (:*:) a b a
x

instance ToText a => GToText (K1 i a) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> K1 i a a -> TextBuilder ()
gToTextBuilder Int
p (K1 a
x) = Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
p a
x

--------------------------------------------------------------------------------
-- Data types
instance GToText f => GToText (D1 c f) where
    {-# INLINE gToTextBuilder #-}
    gToTextBuilder :: Int -> D1 c f a -> TextBuilder ()
gToTextBuilder Int
p (M1 f a
x) = Int -> f a -> TextBuilder ()
forall (f :: * -> *) a. GToText f => Int -> f a -> TextBuilder ()
gToTextBuilder Int
p f a
x


-- | Directly convert data to 'Text'.
toText :: ToText a => a -> Text
{-# INLINE toText #-}
toText :: a -> Text
toText = TextBuilder () -> Text
forall a. TextBuilder a -> Text
buildText (TextBuilder () -> Text) -> (a -> TextBuilder ()) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0

-- | Directly convert data to 'B.Builder'.
toBuilder :: ToText a => a -> B.Builder ()
{-# INLINE toBuilder #-}
toBuilder :: a -> Builder ()
toBuilder = TextBuilder () -> Builder ()
forall a. TextBuilder a -> Builder a
getBuilder (TextBuilder () -> Builder ())
-> (a -> TextBuilder ()) -> a -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0

-- | Directly convert data to 'V.Bytes'.
toBytes :: ToText a => a -> V.Bytes
{-# INLINE toBytes #-}
toBytes :: a -> Bytes
toBytes = Builder () -> Bytes
forall a. Builder a -> Bytes
B.buildBytes (Builder () -> Bytes) -> (a -> Builder ()) -> a -> Bytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  a -> Builder ()
forall a. ToText a => a -> Builder ()
toBuilder

-- | Faster 'show' replacement.
toString :: ToText a => a -> String
{-# INLINE toString #-}
toString :: a -> String
toString = Text -> String
T.unpack (Text -> String) -> (a -> Text) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. ToText a => a -> Text
toText

instance ToText Bool where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Bool -> TextBuilder ()
toTextBuilder Int
_ Bool
True = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"True"
    toTextBuilder Int
_ Bool
_    = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"False"

instance ToText Char where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Char -> TextBuilder ()
toTextBuilder Int
_ = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Char -> Builder ()) -> Char -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.string8 (String -> Builder ()) -> (Char -> String) -> Char -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String
forall a. Show a => a -> String
show

instance ToText Double where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Double -> TextBuilder ()
toTextBuilder Int
_ = Double -> TextBuilder ()
double;}
instance ToText Float  where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Float -> TextBuilder ()
toTextBuilder Int
_ = Float -> TextBuilder ()
float;}

instance ToText Int     where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Int -> TextBuilder ()
toTextBuilder Int
_ = Int -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Int8    where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Int8 -> TextBuilder ()
toTextBuilder Int
_ = Int8 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Int16   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Int16 -> TextBuilder ()
toTextBuilder Int
_ = Int16 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Int32   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Int32 -> TextBuilder ()
toTextBuilder Int
_ = Int32 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Int64   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Int64 -> TextBuilder ()
toTextBuilder Int
_ = Int64 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Word     where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Word -> TextBuilder ()
toTextBuilder Int
_ = Word -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Word8    where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Word8 -> TextBuilder ()
toTextBuilder Int
_ = Word8 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Word16   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Word16 -> TextBuilder ()
toTextBuilder Int
_ = Word16 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Word32   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Word32 -> TextBuilder ()
toTextBuilder Int
_ = Word32 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}
instance ToText Word64   where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Word64 -> TextBuilder ()
toTextBuilder Int
_ = Word64 -> TextBuilder ()
forall a. (Integral a, Bounded a) => a -> TextBuilder ()
int;}

instance ToText Integer  where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Integer -> TextBuilder ()
toTextBuilder Int
_ = Integer -> TextBuilder ()
integer;}
instance ToText Natural  where {{-# INLINE toTextBuilder #-}; toTextBuilder :: Int -> Natural -> TextBuilder ()
toTextBuilder Int
_ = Integer -> TextBuilder ()
integer (Integer -> TextBuilder ())
-> (Natural -> Integer) -> Natural -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral}
instance ToText Ordering where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Ordering -> TextBuilder ()
toTextBuilder Int
_ Ordering
GT = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"GT"
    toTextBuilder Int
_ Ordering
EQ = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"EQ"
    toTextBuilder Int
_ Ordering
_  = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"LT"

instance ToText () where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> () -> TextBuilder ()
toTextBuilder Int
_ () = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"()"

instance ToText Version where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Version -> TextBuilder ()
toTextBuilder Int
_ = String -> TextBuilder ()
stringUTF8 (String -> TextBuilder ())
-> (Version -> String) -> Version -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> String
forall a. Show a => a -> String
show

-- | To keep sync with 'Show' instance's escaping rule, we reuse show here, so it won't be as fast as memcpy.
instance ToText Text where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Text -> TextBuilder ()
toTextBuilder Int
_ = String -> TextBuilder ()
stringUTF8 (String -> TextBuilder ())
-> (Text -> String) -> Text -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
forall a. Show a => a -> String
show

instance ToText Sci.Scientific where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Scientific -> TextBuilder ()
toTextBuilder Int
_ = Scientific -> TextBuilder ()
scientific

instance ToText a => ToText [a] where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> [a] -> TextBuilder ()
toTextBuilder Int
_ = TextBuilder () -> TextBuilder ()
square (TextBuilder () -> TextBuilder ())
-> ([a] -> TextBuilder ()) -> [a] -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder () -> (a -> TextBuilder ()) -> [a] -> TextBuilder ()
forall a.
TextBuilder () -> (a -> TextBuilder ()) -> [a] -> TextBuilder ()
intercalateList TextBuilder ()
comma (Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0)

instance ToText a => ToText (V.Vector a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Vector a -> TextBuilder ()
toTextBuilder Int
_ = TextBuilder () -> TextBuilder ()
square (TextBuilder () -> TextBuilder ())
-> (Vector a -> TextBuilder ()) -> Vector a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder ()
-> (a -> TextBuilder ()) -> Vector a -> TextBuilder ()
forall (v :: * -> *) a.
Vec v a =>
TextBuilder () -> (a -> TextBuilder ()) -> v a -> TextBuilder ()
intercalateVec TextBuilder ()
comma (Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0)

instance (Prim a, ToText a) => ToText (V.PrimVector a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> PrimVector a -> TextBuilder ()
toTextBuilder Int
_ = TextBuilder () -> TextBuilder ()
square (TextBuilder () -> TextBuilder ())
-> (PrimVector a -> TextBuilder ())
-> PrimVector a
-> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextBuilder ()
-> (a -> TextBuilder ()) -> PrimVector a -> TextBuilder ()
forall (v :: * -> *) a.
Vec v a =>
TextBuilder () -> (a -> TextBuilder ()) -> v a -> TextBuilder ()
intercalateVec TextBuilder ()
comma (Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0)

instance (ToText a, ToText b) => ToText (a, b) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b

instance (ToText a, ToText b, ToText c) => ToText (a, b, c) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b, c) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b, c
c) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> c -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 c
c

instance (ToText a, ToText b, ToText c, ToText d) => ToText (a, b, c, d) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b, c, d) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b, c
c, d
d) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> c -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 c
c
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> d -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 d
d

instance (ToText a, ToText b, ToText c, ToText d, ToText e) => ToText (a, b, c, d, e) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b, c, d, e) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b, c
c, d
d, e
e) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> c -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 c
c
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> d -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 d
d
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> e -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 e
e

instance (ToText a, ToText b, ToText c, ToText d, ToText e, ToText f) => ToText (a, b, c, d, e, f) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b, c, d, e, f) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b, c
c, d
d, e
e, f
f) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> c -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 c
c
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> d -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 d
d
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> e -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 e
e
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> f -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 f
f

instance (ToText a, ToText b, ToText c, ToText d, ToText e, ToText f, ToText g) => ToText (a, b, c, d, e, f, g) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> (a, b, c, d, e, f, g) -> TextBuilder ()
toTextBuilder Int
_ (a
a, b
b, c
c, d
d, e
e, f
f, g
g) = TextBuilder () -> TextBuilder ()
paren (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$  Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 a
a
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 b
b
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> c -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 c
c
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> d -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 d
d
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> e -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 e
e
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> f -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 f
f
                     TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TextBuilder ()
comma TextBuilder () -> TextBuilder () -> TextBuilder ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> g -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
0 g
g

instance ToText a => ToText (Maybe a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Maybe a -> TextBuilder ()
toTextBuilder Int
p (Just a
x) = Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"Just "
                                                       Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
11 a
x
    toTextBuilder Int
_ Maybe a
_        = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"Nothing"

instance (ToText a, ToText b) => ToText (Either a b) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Either a b -> TextBuilder ()
toTextBuilder Int
p (Left a
x) = Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"Left "
                                                       Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
11 a
x
    toTextBuilder Int
p (Right b
x) = Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
"Right "
                                                        Int -> b -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
11 b
x

instance (ToText a, Integral a) => ToText (Ratio a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Ratio a -> TextBuilder ()
toTextBuilder Int
p Ratio a
r = Bool -> TextBuilder () -> TextBuilder ()
parenWhen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (TextBuilder () -> TextBuilder ())
-> TextBuilder () -> TextBuilder ()
forall a b. (a -> b) -> a -> b
$ do Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
8 (Ratio a -> a
forall a. Ratio a -> a
numerator Ratio a
r)
                                                Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder Builder ()
" % "
                                                Int -> a -> TextBuilder ()
forall a. ToText a => Int -> a -> TextBuilder ()
toTextBuilder Int
8 (Ratio a -> a
forall a. Ratio a -> a
denominator Ratio a
r)

instance HasResolution a => ToText (Fixed a) where
    {-# INLINE toTextBuilder #-}
    toTextBuilder :: Int -> Fixed a -> TextBuilder ()
toTextBuilder Int
_ = Builder () -> TextBuilder ()
forall a. Builder a -> TextBuilder a
TextBuilder (Builder () -> TextBuilder ())
-> (Fixed a -> Builder ()) -> Fixed a -> TextBuilder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Builder ()
B.string8 (String -> Builder ())
-> (Fixed a -> String) -> Fixed a -> Builder ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  Fixed a -> String
forall a. Show a => a -> String
show

deriving anyclass instance ToText a => ToText (Semigroup.Min a)
deriving anyclass instance ToText a => ToText (Semigroup.Max a)
deriving anyclass instance ToText a => ToText (Semigroup.First a)
deriving anyclass instance ToText a => ToText (Semigroup.Last a)
deriving anyclass instance ToText a => ToText (Semigroup.WrappedMonoid a)
deriving anyclass instance ToText a => ToText (Semigroup.Dual a)
deriving anyclass instance ToText a => ToText (Monoid.First a)
deriving anyclass instance ToText a => ToText (Monoid.Last a)
deriving anyclass instance ToText a => ToText (NonEmpty a)
deriving anyclass instance ToText a => ToText (Identity a)
deriving anyclass instance ToText a => ToText (Const a b)
deriving anyclass instance ToText (Proxy a)
deriving anyclass instance ToText b => ToText (Tagged a b)
deriving anyclass instance ToText (f (g a)) => ToText (Compose f g a)
deriving anyclass instance (ToText (f a), ToText (g a)) => ToText (Product f g a)
deriving anyclass instance (ToText (f a), ToText (g a), ToText a) => ToText (Sum f g a)