crux-0.7: src/Crux/ProgressBar.hs
module Crux.ProgressBar where
import System.IO
import System.Console.ANSI
import Control.Monad(zipWithM)
-- | Callback called with index when a goal is started
type ProverMilestoneStartGoal = Integer -> IO ()
-- | Callback called with index when a goal has ended
type ProverMilestoneEndGoal = Integer -> IO ()
-- | Callback called when all goals have ended
type ProverMilestoneFinish = IO ()
-- | Set of three callbacks called by the prover to let loggers indicate
-- progress of the proving process.
type ProverMilestoneCallbacks =
( ProverMilestoneStartGoal
, ProverMilestoneEndGoal
, ProverMilestoneFinish
)
silentProverMilestoneCallbacks :: ProverMilestoneCallbacks
silentProverMilestoneCallbacks =
(const (return ()), const (return ()), return ())
prepStatus :: String -> Int -> IO ProverMilestoneCallbacks
prepStatus pref tot =
do ansi <- hSupportsANSI stdout
if ansi then
return (start,end,finish)
else
return silentProverMilestoneCallbacks
where
start n = do hSaveCursor stdout
hPutStr stdout (msg n)
hFlush stdout
end _n = do hRestoreCursor stdout
hFlush stdout
finish = do hClearLine stdout
hFlush stdout
totS = show tot
totW = length totS
sh x = let y = show x
in replicate (totW - length y) ' ' ++ y
msg n = pref ++ sh (n::Integer) ++ " / " ++ totS
withProgressBar' :: String -> [a] -> (a -> IO b) -> IO [b]
withProgressBar' pref xs f =
do (start,end,finish) <- prepStatus pref (length xs)
let one n a =
do start n
b <- f a
end n
return b
zipWithM one [ 1 .. ] xs <* finish
withProgressBar :: Int -> [a] -> (a -> IO b) -> IO [b]
withProgressBar w xs f =
do prt "|"
go 0 0 xs []
where
prt x = do putStr x
hFlush stdout
step = fromIntegral w / fromIntegral (length xs) :: Float
go shown loc todo done =
do let new = floor loc - shown
prt (replicate (floor loc - shown) '=')
case todo of
[] -> prt "|\n" >> return (reverse done)
a : as ->
do b <- f a
go (shown + new) (loc + step) as (b : done)