Skip to content

Commit 7691243

Browse files
committed
dist: extract DownloadStatus type
1 parent df6ad26 commit 7691243

File tree

1 file changed

+89
-54
lines changed

1 file changed

+89
-54
lines changed

src/dist/download.rs

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,8 @@ impl<'a> DownloadCfg<'a> {
192192
pub(crate) struct DownloadTracker {
193193
/// MultiProgress bar for the downloads.
194194
multi_progress_bars: MultiProgress,
195-
/// Mapping of URLs being downloaded to their corresponding progress bars.
196-
/// The `Option<Instant>` represents the instant where the download is being retried,
197-
/// allowing us delay the reappearance of the progress bar so that the user can see
198-
/// the message "retrying download" for at least a second.
199-
/// Without it, the progress bar would reappear immediately, not allowing the user to
200-
/// correctly see the message, before the progress bar starts again.
201-
file_progress_bars: Mutex<HashMap<String, (ProgressBar, Option<Instant>)>>,
195+
/// Mapping of URLs being downloaded to their corresponding download status.
196+
file_progress_bars: Mutex<HashMap<String, DownloadStatus>>,
202197
}
203198

204199
impl DownloadTracker {
@@ -218,42 +213,96 @@ impl DownloadTracker {
218213

219214
/// Creates a new ProgressBar for the given component.
220215
pub(crate) fn create_progress_bar(&self, component: String, url: String) {
221-
let pb = ProgressBar::hidden();
222-
pb.set_style(
223-
ProgressStyle::with_template(
224-
"{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})",
225-
)
226-
.unwrap()
227-
.progress_chars("## "),
228-
);
229-
pb.set_message(component);
230-
self.multi_progress_bars.add(pb.clone());
231-
self.file_progress_bars
232-
.lock()
233-
.unwrap()
234-
.insert(url, (pb, None));
216+
let status = DownloadStatus::new(component);
217+
self.multi_progress_bars.add(status.progress.clone());
218+
self.file_progress_bars.lock().unwrap().insert(url, status);
235219
}
236220

237221
/// Sets the length for a new ProgressBar and gives it a style.
238222
pub(crate) fn content_length_received(&self, content_len: u64, url: &str) {
239-
if let Some((pb, _)) = self.file_progress_bars.lock().unwrap().get(url) {
240-
pb.reset();
241-
pb.set_length(content_len);
223+
if let Some(status) = self.file_progress_bars.lock().unwrap().get(url) {
224+
status.received_length(content_len);
242225
}
243226
}
244227

245228
/// Notifies self that data of size `len` has been received.
246229
pub(crate) fn data_received(&self, len: usize, url: &str) {
247230
let mut map = self.file_progress_bars.lock().unwrap();
248-
let Some((pb, retry_time)) = map.get_mut(url) else {
249-
return;
231+
if let Some(status) = map.get_mut(url) {
232+
status.received_data(len);
250233
};
251-
pb.inc(len as u64);
252-
if !retry_time.is_some_and(|instant| instant.elapsed() > Duration::from_secs(1)) {
234+
}
235+
236+
/// Notifies self that the download has finished.
237+
pub(crate) fn download_finished(&self, url: &str) {
238+
let map = self.file_progress_bars.lock().unwrap();
239+
if let Some(status) = map.get(url) {
240+
status.finished()
241+
};
242+
}
243+
244+
/// Notifies self that the download has failed.
245+
pub(crate) fn download_failed(&self, url: &str) {
246+
let map = self.file_progress_bars.lock().unwrap();
247+
if let Some(status) = map.get(url) {
248+
status.failed();
249+
};
250+
}
251+
252+
/// Notifies self that the download is being retried.
253+
pub(crate) fn retrying_download(&self, url: &str) {
254+
let mut map = self.file_progress_bars.lock().unwrap();
255+
if let Some(status) = map.get_mut(url) {
256+
status.retrying();
257+
};
258+
}
259+
}
260+
261+
struct DownloadStatus {
262+
progress: ProgressBar,
263+
/// The instant where the download is being retried.
264+
///
265+
/// Allows us to delay the reappearance of the progress bar so that the user can see
266+
/// the message "retrying download" for at least a second. Without it, the progress
267+
/// bar would reappear immediately, not allowing the user to correctly see the message,
268+
/// before the progress bar starts again.
269+
retry_time: Option<Instant>,
270+
}
271+
272+
impl DownloadStatus {
273+
fn new(component: String) -> Self {
274+
let progress = ProgressBar::hidden();
275+
progress.set_style(
276+
ProgressStyle::with_template(
277+
"{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})",
278+
)
279+
.unwrap()
280+
.progress_chars("## "),
281+
);
282+
progress.set_message(component);
283+
284+
Self {
285+
progress,
286+
retry_time: None,
287+
}
288+
}
289+
290+
fn received_length(&self, len: u64) {
291+
self.progress.reset();
292+
self.progress.set_length(len);
293+
}
294+
295+
fn received_data(&mut self, len: usize) {
296+
self.progress.inc(len as u64);
297+
if !self
298+
.retry_time
299+
.is_some_and(|instant| instant.elapsed() > Duration::from_secs(1))
300+
{
253301
return;
254302
}
255-
*retry_time = None;
256-
pb.set_style(
303+
304+
self.retry_time = None;
305+
self.progress.set_style(
257306
ProgressStyle::with_template(
258307
"{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})",
259308
)
@@ -262,40 +311,26 @@ impl DownloadTracker {
262311
);
263312
}
264313

265-
/// Notifies self that the download has finished.
266-
pub(crate) fn download_finished(&self, url: &str) {
267-
let map = self.file_progress_bars.lock().unwrap();
268-
let Some((pb, _)) = map.get(url) else {
269-
return;
270-
};
271-
pb.set_style(
314+
fn finished(&self) {
315+
self.progress.set_style(
272316
ProgressStyle::with_template("{msg:>12.bold} downloaded {total_bytes} in {elapsed}")
273317
.unwrap(),
274318
);
275-
pb.finish();
319+
self.progress.finish();
276320
}
277321

278-
/// Notifies self that the download has failed.
279-
pub(crate) fn download_failed(&self, url: &str) {
280-
let map = self.file_progress_bars.lock().unwrap();
281-
let Some((pb, _)) = map.get(url) else {
282-
return;
283-
};
284-
pb.set_style(
322+
fn failed(&self) {
323+
self.progress.set_style(
285324
ProgressStyle::with_template("{msg:>12.bold} download failed after {elapsed}")
286325
.unwrap(),
287326
);
288-
pb.finish();
327+
self.progress.finish();
289328
}
290329

291-
/// Notifies self that the download is being retried.
292-
pub(crate) fn retrying_download(&self, url: &str) {
293-
let mut map = self.file_progress_bars.lock().unwrap();
294-
let Some((pb, retry_time)) = map.get_mut(url) else {
295-
return;
296-
};
297-
*retry_time = Some(Instant::now());
298-
pb.set_style(ProgressStyle::with_template("{msg:>12.bold} retrying download").unwrap());
330+
fn retrying(&mut self) {
331+
self.retry_time = Some(Instant::now());
332+
self.progress
333+
.set_style(ProgressStyle::with_template("{msg:>12.bold} retrying download").unwrap());
299334
}
300335
}
301336

0 commit comments

Comments
 (0)