{-# LANGUAGE OverloadedStrings    #-}

-- | Wrapper around `Data.Text.Builder` that exports some useful combinators

module Language.Fixpoint.Utils.Builder
  ( fromText
  , fromString
  , parens
  , (<+>)
  , parenSeqs
  , seqs
  , key
  , key2
  , key3
  , bShow
  , bFloat
  ) where

import           Data.Foldable (fold)
import           Data.String
import Data.ByteString.Builder (Builder)
import qualified Data.ByteString.Builder as B
import qualified Data.Text              as T
import qualified Data.Text.Encoding     as T
import qualified Data.List              as L
import qualified Numeric


fromText :: T.Text -> Builder
fromText :: Text -> Builder
fromText Text
t = ByteString -> Builder
B.byteString forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
t

parens :: Builder -> Builder
parens :: Builder -> Builder
parens Builder
b = Builder
"(" forall a. Semigroup a => a -> a -> a
<>  Builder
b forall a. Semigroup a => a -> a -> a
<> Builder
")"

infixl 9 <+>
(<+>) :: Builder -> Builder -> Builder
Builder
x <+> :: Builder -> Builder -> Builder
<+> Builder
y = Builder
x forall a. Semigroup a => a -> a -> a
<> Builder
" " forall a. Semigroup a => a -> a -> a
<> Builder
y

parenSeqs :: [Builder] -> Builder
parenSeqs :: [Builder] -> Builder
parenSeqs = Builder -> Builder
parens forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Builder] -> Builder
seqs

key :: Builder -> Builder -> Builder
key :: Builder -> Builder -> Builder
key Builder
k Builder
b = [Builder] -> Builder
parenSeqs [Builder
k, Builder
b]

key2 :: Builder -> Builder -> Builder -> Builder
key2 :: Builder -> Builder -> Builder -> Builder
key2 Builder
k Builder
b1 Builder
b2 = [Builder] -> Builder
parenSeqs [Builder
k, Builder
b1, Builder
b2]

key3 :: Builder -> Builder -> Builder -> Builder ->  Builder
key3 :: Builder -> Builder -> Builder -> Builder -> Builder
key3 Builder
k Builder
b1 Builder
b2 Builder
b3 = [Builder] -> Builder
parenSeqs [Builder
k, Builder
b1, Builder
b2, Builder
b3]

seqs :: [Builder] -> Builder
seqs :: [Builder] -> Builder
seqs = forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
L.intersperse Builder
" "

bShow :: Show a => a -> Builder
bShow :: forall a. Show a => a -> Builder
bShow = forall a. IsString a => String -> a
fromString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show

bFloat :: RealFloat a => a -> Builder
bFloat :: forall a. RealFloat a => a -> Builder
bFloat a
d = forall a. IsString a => String -> a
fromString (forall a. RealFloat a => Maybe Int -> a -> ShowS
Numeric.showFFloat forall a. Maybe a
Nothing a
d String
"")