{-# LANGUAGE OverloadedStrings, RelaxedPolyRec #-}-- |-- 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.moduleData.Text.Format(-- * TypesFormat,Only(..)-- ** Types for format control,Shown(..)-- * Rendering,format,print,hprint,build-- * Format control,left,right-- ** Integers,hex-- ** Floating point numbers,expt,fixed,prec,shortest)whereimportControl.Monad.IO.Class(MonadIO(liftIO))importData.Text.Format.Functions((<>))importData.Text.Format.Params(Params(..))importData.Text.Format.Types.Internal(Format(..),Only(..),Shown(..))importData.Text.Format.Types.Internal(Hex(..))importData.Text.Lazy.BuilderimportPreludehiding(exp,print)importSystem.IO(Handle)importqualifiedData.Double.Conversion.TextasCimportqualifiedData.TextasSTimportqualifiedData.Text.BuildableasBimportqualifiedData.Text.LazyasLTimportqualifiedData.Text.Lazy.IOasLT-- Format strings are almost always constants, and they're expensive-- to interpret (which we refer to as "cracking" here). We'd really-- like to have GHC memoize the cracking of a known-constant format-- string, so that it occurs at most once.---- To achieve this, we arrange to have the cracked version of a format-- string let-floated out as a CAF, by inlining the definitions of-- build and functions that invoke it. This works well with GHC 7.-- | Render a format string and arguments to a 'Builder'.build::Paramsps=>Format->ps->Builderbuildfmtps=zipParams(crackfmt)(buildParamsps){-# INLINE build #-}zipParams::[Builder]->[Builder]->BuilderzipParamsfragmentsparams=gofragmentsparamswherego(f:fs)(y:ys)=f<>y<>gofsysgo[f][]=fgo__=error.LT.unpack$format"Data.Text.Format.build: {} sites, but {} parameters"(lengthfragments-1,lengthparams)crack::Format->[Builder]crack=mapfromText.ST.splitOn"{}".fromFormat-- | Render a format string and arguments to a 'LT.Text'.format::Paramsps=>Format->ps->LT.Textformatfmtps=toLazyText$buildfmtps{-# INLINE format #-}-- | Render a format string and arguments, then print the result.print::(MonadIOm,Paramsps)=>Format->ps->m()printfmtps=liftIO.LT.putStr.toLazyText$buildfmtps{-# INLINE print #-}-- | Render a format string and arguments, then print the result to-- the given file handle.hprint::(MonadIOm,Paramsps)=>Handle->Format->ps->m()hprinthfmtps=liftIO.LT.hPutStrh.toLazyText$buildfmtps{-# INLINE hprint #-}-- | Pad the left hand side of a string until it reaches @k@-- characters wide, if necessary filling with character @c@.left::B.Buildablea=>Int->Char->a->Builderleftkc=fromLazyText.LT.justifyRight(fromIntegralk)c.toLazyText.B.build-- | Pad the right hand side of a string until it reaches @k@-- characters wide, if necessary filling with character @c@.right::B.Buildablea=>Int->Char->a->Builderrightkc=fromLazyText.LT.justifyLeft(fromIntegralk)c.toLazyText.B.build-- | Render a floating point number, with the given number of digits-- of precision. Uses decimal notation for values between @0.1@ and-- @9,999,999@, and scientific notation otherwise.prec::(Reala)=>Int-- ^ Number of digits of precision.->a->Builder{-# RULES "prec/Double"
forall d x. prec d (x::Double) = B.build (C.toPrecision d x) #-}precdigits=B.build.C.toPrecisiondigits.realToFrac-- | Render a floating point number using normal notation, with the-- given number of decimal places.fixed::(Reala)=>Int-- ^ Number of digits of precision after the decimal.->a->Builderfixeddecs=B.build.C.toFixeddecs.realToFrac{-# RULES "fixed/Double"
forall d x. fixed d (x::Double) = B.build (C.toFixed d x) #-}-- | Render a floating point number using scientific/engineering-- notation (e.g. @2.3e123@), with the given number of decimal places.expt::(Reala)=>Int-- ^ Number of digits of precision after the decimal.->a->Builderexptdecs=B.build.C.toExponentialdecs.realToFrac{-# RULES "expt/Double"
forall d x. expt d (x::Double) = B.build (C.toExponential d x) #-}-- | Render a floating point number using the smallest number of-- digits that correctly represent it.shortest::(Reala)=>a->Buildershortest=B.build.C.toShortest.realToFrac{-# RULES "shortest/Double"
forall x. shortest (x::Double) = B.build (C.toShortest x) #-}-- | Render an integer using hexadecimal notation. (No leading "0x"-- is added.)hex::Integrala=>a->Builderhex=B.build.Hex{-# INLINE hex #-}