trackProgressString :: String -> Maybe Word64 -> (String -> IO ()) ->
                       IO (ByteString -> IO ByteString)
trackProgressString formatStr mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgress (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- |Exactly as 'trackProgressString', but use the given chunkSize instead
-- of the default chunk size.
trackProgressString :: String -> Maybe Word64 -> (String -> IO ()) ->
                       IO (ByteString -> IO ByteString)
trackProgressString formatStr mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgress (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- |Exactly as 'trackProgressString', but use the given chunkSize instead
-- of the default chunk size.
trackProgressString formatStr mTotal tracker = do
  startTime <- getCurrentTime
  return (trackProgress (handler startTime))
 where
  handler startTime chunkSize total = do
    now <- getCurrentTime
    tracker (buildString formatStr startTime now mTotal chunkSize total)

-- |Exactly as 'trackProgressString', but use the given chunkSize instead
-- of the default chunk size.