trackProgressStringWithChunkSize :: String -- ^the format string
                                    -> Word64 -- ^the chunk size
                                    -> Maybe Word64 -- ^total size (opt.)
                                    -> (String -> IO ()) -- ^the action
                                    -> IO (ByteString -> IO ByteString)
trackProgressStringWithChunkSize formatStr chunk mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgressWithChunkSize chunk (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- build a progress string for trackProgressString et al
trackProgressStringWithChunkSize :: String -- ^the format string
                                    -> Word64 -- ^the chunk size
                                    -> Maybe Word64 -- ^total size (opt.)
                                    -> (String -> IO ()) -- ^the action
                                    -> IO (ByteString -> IO ByteString)
trackProgressStringWithChunkSize formatStr chunk mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgressWithChunkSize chunk (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- build a progress string for trackProgressString et al
trackProgressStringWithChunkSize formatStr chunk mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgressWithChunkSize chunk (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- build a progress string for trackProgressString et al