8000 feat(progress): show estimated time remaining by AK-Lmn · Pull Request #6 · osmanahmadxai/beemr · GitHub
[go: up one dir, main page]

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::time::{Duration, Instant};
use crate::util::format_bytes;

const REDRAW_EVERY: Duration = Duration::from_millis(100);
// Keeps the whole line within 80 columns.
const BAR_WIDTH: usize = 20;
// Keeps the whole line within 80 columns, even with an ETA like " ~1h 20m left".
const BAR_WIDTH: usize = 10;

pub struct Progress {
label: &'static str,
Expand All @@ -16,6 +16,7 @@ pub struct Progress {
started: Instant,
last_draw: Option<Instant>,
enabled: bool,
finished: bool,
}

impl Progress {
Expand All @@ -27,6 +28,7 @@ impl Progress {
started: Instant::now(),
last_draw: None,
enabled: std::io::stderr().is_terminal(),
finished: false,
}
}

Expand All @@ -40,6 +42,7 @@ impl Progress {

pub fn finish(&mut self) {
if self.enabled {
self.finished = true;
self.draw();
eprintln!();
}
Expand All @@ -53,16 +56,25 @@ impl Progress {
};
let filled = (fraction * BAR_WIDTH as f64) as usize;
let rate = self.done as f64 / self.started.elapsed().as_secs_f64().max(0.001);
let eta = if !self.finished && self.done > 0 && self.done < self.total && rate > 0.0 {
let remaining_bytes = self.total - self.done;
let remaining_secs = remaining_bytes as f64 / rate;
let duration = Duration::from_secs(remaining_secs.round() as u64);
format!(" ~{} left", crate::util::format_duration(duration))
} else {
String::new()
};
eprint!(
// \x1b[K clears the rest of the line instead of padding with spaces.
"\r {} [{}{}] {:5.1}% {} / {} {}/s\x1b[K",
"\r {} [{}{}] {:5.1}% {} / {} {}/s{}\x1b[K",
self.label,
"=".repeat(filled),
" ".repeat(BAR_WIDTH - filled),
fraction * 100.0,
format_bytes(self.done),
format_bytes(self.total),
format_bytes(rate as u64),
eta,
);
let _ = std::io::stderr().flush();
}
Expand Down
0