{-# LANGUAGE CPP, FlexibleInstances, Rank2Types, TypeSynonymInstances #-}
module Gauge.IO.Printf
(
CritHPrintfType
, note
, printError
, prolix
, rewindClearLine
) where
import Control.Monad (when)
import Gauge.Monad (Gauge, askConfig, gaugeIO)
import Gauge.Main.Options (Config(verbosity), Verbosity(..))
import System.IO (Handle, hFlush, stderr, stdout)
import Text.Printf (PrintfArg)
import qualified Text.Printf (HPrintfType, hPrintf)
data PrintfCont = PrintfCont (IO ()) (forall a . PrintfArg a => a -> PrintfCont)
class CritHPrintfType a where
chPrintfImpl :: (Config -> Bool) -> PrintfCont -> a
instance CritHPrintfType (Gauge a) where
chPrintfImpl check (PrintfCont final _)
= do x <- askConfig
when (check x) (gaugeIO (final >> hFlush stderr >> hFlush stdout))
return undefined
instance CritHPrintfType (IO a) where
chPrintfImpl _ (PrintfCont final _)
= final >> hFlush stderr >> hFlush stdout >> return undefined
instance (CritHPrintfType r, PrintfArg a) => CritHPrintfType (a -> r) where
chPrintfImpl check (PrintfCont _ anotherArg) x
= chPrintfImpl check (anotherArg x)
chPrintf :: CritHPrintfType r => (Config -> Bool) -> Handle -> String -> r
chPrintf shouldPrint h s
= chPrintfImpl shouldPrint (make (Text.Printf.hPrintf h s)
(Text.Printf.hPrintf h s))
where
make :: IO () -> (forall a r. (PrintfArg a, Text.Printf.HPrintfType r) =>
a -> r) -> PrintfCont
make curCall curCall' = PrintfCont curCall (\x -> make (curCall' x)
(curCall' x))
note :: (CritHPrintfType r) => String -> r
note = chPrintf ((> Quiet) . verbosity) stdout
prolix :: (CritHPrintfType r) => String -> r
prolix = chPrintf ((== Verbose) . verbosity) stdout
printError :: (CritHPrintfType r) => String -> r
printError = chPrintf (const True) stderr
rewindClearLine :: String
#ifdef mingw32_HOST_OS
rewindClearLine = "\n"
#else
rewindClearLine = "\r\ESC[0K"
#endif