{-# LANGUAGE RelaxedPolyRec #-}
{-# LANGUAGE CPP #-}

-- |
-- Module      : Data.Text.Format
-- Copyright   : (c) 2011 MailRank, Inc.
--
-- License     : BSD-style
-- Maintainer  : bos@serpentine.com
-- Stability   : experimental
-- Portability : GHC
--
-- Fast, efficient, flexible support for formatting text strings.

module Data.Text.Format
    (
    -- * Format control
     left
    , right
    -- ** Integers
    , hex
    -- ** Floating point numbers
    , fixed
    , shortest
    ) where

#ifdef ghcjs_HOST_OS
import           Text.Printf
#else
import           Data.Double.Conversion.Text (toFixed, toShortest)
#endif
import qualified Formatting.Buildable as B
import           Data.Text.Format.Types (Hex(..))
import qualified Data.Text.Lazy as LT
import           Data.Text.Lazy.Builder
import           Prelude hiding (exp, print)

-- | Pad the left hand side of a string until it reaches @k@
-- characters wide, if necessary filling with character @c@.
left :: B.Buildable a => Int -> Char -> a -> Builder
left :: Int -> Char -> a -> Builder
left Int
k Char
c =
    Text -> Builder
fromLazyText (Text -> Builder) -> (a -> Text) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Char -> Text -> Text
LT.justifyRight (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k) Char
c (Text -> Text) -> (a -> Text) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder
forall p. Buildable p => p -> Builder
B.build

-- | Pad the right hand side of a string until it reaches @k@
-- characters wide, if necessary filling with character @c@.
right :: B.Buildable a => Int -> Char -> a -> Builder
right :: Int -> Char -> a -> Builder
right Int
k Char
c =
    Text -> Builder
fromLazyText (Text -> Builder) -> (a -> Text) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Char -> Text -> Text
LT.justifyLeft (Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k) Char
c (Text -> Text) -> (a -> Text) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder
forall p. Buildable p => p -> Builder
B.build

-- | Render a floating point number using normal notation, with the
-- given number of decimal places.
fixed :: (Real a) =>
         Int
      -- ^ Number of digits of precision after the decimal.
      -> a -> Builder
#ifdef ghcjs_HOST_OS
fixed decs = fromString . toFixed . realToFrac
  where
    toFixed :: Double -> String
    toFixed = printf ("%f." ++ show decs)
#else
fixed :: Int -> a -> Builder
fixed Int
decs = Text -> Builder
fromText (Text -> Builder) -> (a -> Text) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Double -> Text
toFixed Int
decs (Double -> Text) -> (a -> Double) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac
#endif
{-# NOINLINE[0] fixed #-}

-- | Render a floating point number using the smallest number of
-- digits that correctly represent it.
shortest :: Real a => a -> Builder
#ifdef ghcjs_HOST_OS
shortest = fromString . toShortest . realToFrac
  where
    toShortest :: Double -> String
    toShortest = printf "%f"
#else
shortest :: a -> Builder
shortest = Text -> Builder
fromText (Text -> Builder) -> (a -> Text) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Text
toShortest (Double -> Text) -> (a -> Double) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac
#endif
{-# INLINE shortest #-}

-- | Render an integer using hexadecimal notation.  (No leading "0x"
-- is added.)
hex :: Integral a => a -> Builder
hex :: a -> Builder
hex = Hex a -> Builder
forall p. Buildable p => p -> Builder
B.build (Hex a -> Builder) -> (a -> Hex a) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Hex a
forall a. a -> Hex a
Hex
{-# INLINE hex #-}