use std::collections::HashMap;
use std::sync::Mutex;
use crate::progress::task::TaskId;
use crate::progress::{format_time, ProgressColumn, Task};
use crate::style::Style;
use crate::text::Text;
#[derive(Debug, Clone)]
pub struct TimeElapsedColumn;
impl Default for TimeElapsedColumn {
fn default() -> Self {
Self
}
}
impl ProgressColumn for TimeElapsedColumn {
fn render(&self, task: &Task) -> Text {
let elapsed = task.elapsed().unwrap_or(0.0);
let formatted = format_time(elapsed);
Text::new(&formatted, Style::parse("progress.elapsed"))
}
}
pub struct TimeRemainingColumn {
pub compact: bool,
pub elapsed_when_finished: bool,
cache: Mutex<HashMap<TaskId, (f64, Text)>>,
}
impl std::fmt::Debug for TimeRemainingColumn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TimeRemainingColumn")
.field("compact", &self.compact)
.field("elapsed_when_finished", &self.elapsed_when_finished)
.finish()
}
}
impl Clone for TimeRemainingColumn {
fn clone(&self) -> Self {
TimeRemainingColumn {
compact: self.compact,
elapsed_when_finished: self.elapsed_when_finished,
cache: Mutex::new(HashMap::new()),
}
}
}
impl TimeRemainingColumn {
pub fn new() -> Self {
TimeRemainingColumn {
compact: false,
elapsed_when_finished: false,
cache: Mutex::new(HashMap::new()),
}
}
#[must_use]
pub fn with_compact(mut self, compact: bool) -> Self {
self.compact = compact;
self
}
#[must_use]
pub fn with_elapsed_when_finished(mut self, elapsed_when_finished: bool) -> Self {
self.elapsed_when_finished = elapsed_when_finished;
self
}
fn render_fresh(&self, task: &Task) -> Text {
let style = Style::parse("progress.remaining");
if task.finished() {
if self.elapsed_when_finished {
let elapsed = task.elapsed().unwrap_or(0.0);
return Text::new(&format_time(elapsed), style);
}
return Text::new("0:00", style);
}
match task.time_remaining() {
Some(remaining) if remaining.is_finite() => Text::new(&format_time(remaining), style),
_ => Text::new("-:--:--", style),
}
}
}
impl Default for TimeRemainingColumn {
fn default() -> Self {
Self::new()
}
}
impl ProgressColumn for TimeRemainingColumn {
fn max_refresh(&self) -> Option<f64> {
Some(0.5)
}
fn render(&self, task: &Task) -> Text {
let now = task
.elapsed()
.unwrap_or_else(crate::progress::task::current_time_secs);
let mut cache = self.cache.lock().unwrap();
if let Some(&(last_time, ref cached)) = cache.get(&task.id) {
if now - last_time < self.max_refresh().unwrap_or(0.5) {
return cached.clone();
}
}
let fresh = self.render_fresh(task);
cache.insert(task.id, (now, fresh.clone()));
fresh
}
}