Skip to content

Commit fd6c31f

Browse files
committed
Customisable tracker units
Files are in bytes, but other things we may track are not.
1 parent d78ce04 commit fd6c31f

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

src/cli/download_tracker.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub struct DownloadTracker {
4242
/// If we have displayed progress, this is the number of characters we
4343
/// rendered, so we can erase it cleanly.
4444
displayed_charcount: Option<usize>,
45+
/// What units to show progress in
46+
units: Vec<String>,
4547
}
4648

4749
impl DownloadTracker {
@@ -56,6 +58,7 @@ impl DownloadTracker {
5658
last_sec: None,
5759
term: term2::stdout(),
5860
displayed_charcount: None,
61+
units: vec!["B".into(); 1],
5962
}
6063
}
6164

@@ -76,6 +79,15 @@ impl DownloadTracker {
7679
self.download_finished();
7780
true
7881
}
82+
Notification::Install(In::Utils(Un::DownloadPushUnits(units))) => {
83+
self.push_units(units.into());
84+
true
85+
}
86+
Notification::Install(In::Utils(Un::DownloadPopUnits)) => {
87+
self.pop_units();
88+
true
89+
}
90+
7991
_ => false,
8092
}
8193
}
@@ -139,11 +151,13 @@ impl DownloadTracker {
139151
}
140152
/// Display the tracked download information to the terminal.
141153
fn display(&mut self) {
142-
let total_h = Size(self.total_downloaded);
154+
// Panic if someone pops the default bytes unit...
155+
let units = &self.units.last().unwrap();
156+
let total_h = Size(self.total_downloaded, units);
143157
let sum = self.downloaded_last_few_secs.iter().fold(0, |a, &v| a + v);
144158
let len = self.downloaded_last_few_secs.len();
145159
let speed = if len > 0 { sum / len } else { 0 };
146-
let speed_h = Size(speed);
160+
let speed_h = Size(speed, units);
147161
let elapsed_h = Duration(precise_time_s() - self.start_sec);
148162

149163
// First, move to the start of the current line and clear it.
@@ -163,7 +177,7 @@ impl DownloadTracker {
163177

164178
let output = match self.content_len {
165179
Some(content_len) => {
166-
let content_len_h = Size(content_len);
180+
let content_len_h = Size(content_len, units);
167181
let content_len = content_len as f64;
168182
let percent = (self.total_downloaded as f64 / content_len) * 100.;
169183
let remaining = content_len - self.total_downloaded as f64;
@@ -184,6 +198,14 @@ impl DownloadTracker {
184198
let _ = self.term.flush();
185199
self.displayed_charcount = Some(output.chars().count());
186200
}
201+
202+
pub fn push_units(&mut self, new_units: String) {
203+
self.units.push(new_units);
204+
}
205+
206+
pub fn pop_units(&mut self) {
207+
self.units.pop();
208+
}
187209
}
188210

189211
/// Human readable representation of duration(seconds).
@@ -207,21 +229,21 @@ impl fmt::Display for Duration {
207229
}
208230
}
209231

210-
/// Human readable size (bytes)
211-
struct Size(usize);
232+
/// Human readable size (some units)
233+
struct Size<'a>(usize, &'a str);
212234

213-
impl fmt::Display for Size {
235+
impl<'a> fmt::Display for Size<'a> {
214236
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215-
const KIB: f64 = 1024.0;
216-
const MIB: f64 = KIB * KIB;
237+
const KI: f64 = 1024.0;
238+
const MI: f64 = KI * KI;
217239
let size = self.0 as f64;
218240

219-
if size >= MIB {
220-
write!(f, "{:5.1} MiB", size / MIB) // XYZ.P MiB
221-
} else if size >= KIB {
222-
write!(f, "{:5.1} KiB", size / KIB)
241+
if size >= MI {
242+
write!(f, "{:5.1} Mi{}", size / MI, self.1) // XYZ.P Mi
243+
} else if size >= KI {
244+
write!(f, "{:5.1} Ki{}", size / KI, self.1)
223245
} else {
224-
write!(f, "{:3.0} B", size)
246+
write!(f, "{:3.0} {}", size, self.1)
225247
}
226248
}
227249
}

src/utils/notifications.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ pub enum Notification<'a> {
1818
DownloadDataReceived(&'a [u8]),
1919
/// Download has finished.
2020
DownloadFinished,
21+
/// This thins we're tracking is not counted in bytes.
22+
/// Must be paired with a pop-units; our other calls are not
23+
/// setup to guarantee this any better.
24+
DownloadPushUnits(&'a str),
25+
/// finish using an unusual unit.
26+
DownloadPopUnits,
2127
NoCanonicalPath(&'a Path),
2228
ResumingPartialDownload,
2329
UsingCurl,
@@ -34,6 +40,8 @@ impl<'a> Notification<'a> {
3440
| DownloadingFile(_, _)
3541
| DownloadContentLengthReceived(_)
3642
| DownloadDataReceived(_)
43+
| DownloadPushUnits(_)
44+
| DownloadPopUnits
3745
| DownloadFinished
3846
| ResumingPartialDownload
3947
| UsingCurl
@@ -58,6 +66,8 @@ impl<'a> Display for Notification<'a> {
5866
DownloadingFile(url, _) => write!(f, "downloading file from: '{}'", url),
5967
DownloadContentLengthReceived(len) => write!(f, "download size is: '{}'", len),
6068
DownloadDataReceived(data) => write!(f, "received some data of size {}", data.len()),
69+
DownloadPushUnits(_) => Ok(()),
70+
DownloadPopUnits => Ok(()),
6171
DownloadFinished => write!(f, "download finished"),
6272
NoCanonicalPath(path) => write!(f, "could not canonicalize path: '{}'", path.display()),
6373
ResumingPartialDownload => write!(f, "resuming partial download"),

0 commit comments

Comments
 (0)