1- use std:: collections :: HashMap ;
1+ use std:: borrow :: Cow ;
22use std:: fs;
33use std:: ops;
44use std:: path:: { Path , PathBuf } ;
@@ -76,7 +76,7 @@ impl<'a> DownloadCfg<'a> {
7676 & partial_file_path,
7777 Some ( & mut hasher) ,
7878 true ,
79- & self . tracker ,
79+ None ,
8080 self . process ,
8181 )
8282 . await
@@ -125,7 +125,7 @@ impl<'a> DownloadCfg<'a> {
125125 let hash_url = utils:: parse_url ( & ( url. to_owned ( ) + ".sha256" ) ) ?;
126126 let hash_file = self . tmp_cx . new_file ( ) ?;
127127
128- download_file ( & hash_url, & hash_file, None , & self . tracker , self . process ) . await ?;
128+ download_file ( & hash_url, & hash_file, None , None , self . process ) . await ?;
129129
130130 utils:: read_file ( "hash" , & hash_file) . map ( |s| s[ 0 ..64 ] . to_owned ( ) )
131131 }
@@ -139,6 +139,7 @@ impl<'a> DownloadCfg<'a> {
139139 & self ,
140140 url_str : & str ,
141141 update_hash : Option < & Path > ,
142+ status : Option < & DownloadStatus > ,
142143 ext : & str ,
143144 ) -> Result < Option < ( temp:: File , String ) > > {
144145 let hash = self . download_hash ( url_str) . await ?;
@@ -166,7 +167,7 @@ impl<'a> DownloadCfg<'a> {
166167 let file = self . tmp_cx . new_file_with_ext ( "" , ext) ?;
167168
168169 let mut hasher = Sha256 :: new ( ) ;
169- download_file ( & url, & file, Some ( & mut hasher) , & self . tracker , self . process ) . await ?;
170+ download_file ( & url, & file, Some ( & mut hasher) , status , self . process ) . await ?;
170171 let actual_hash = format ! ( "{:x}" , hasher. finalize( ) ) ;
171172
172173 if hash != actual_hash {
@@ -192,13 +193,6 @@ impl<'a> DownloadCfg<'a> {
192193pub ( crate ) struct DownloadTracker {
193194 /// MultiProgress bar for the downloads.
194195 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 , DownloadStatus > > ,
202196}
203197
204198impl DownloadTracker {
@@ -212,64 +206,24 @@ impl DownloadTracker {
212206
213207 Self {
214208 multi_progress_bars,
215- file_progress_bars : Mutex :: new ( HashMap :: new ( ) ) ,
216209 }
217210 }
218211
219212 /// Creates a new ProgressBar for the given component.
220- pub ( crate ) fn create_progress_bar ( & self , component : String , url : String ) {
213+ pub ( crate ) fn status_for ( & self , component : impl Into < Cow < ' static , str > > ) -> DownloadStatus {
221214 let status = DownloadStatus :: new ( component) ;
222215 self . multi_progress_bars . add ( status. progress . clone ( ) ) ;
223- self . file_progress_bars . lock ( ) . unwrap ( ) . insert ( url, status) ;
224- }
225-
226- /// Sets the length for a new ProgressBar and gives it a style.
227- pub ( crate ) fn content_length_received ( & self , content_len : u64 , url : & str ) {
228- if let Some ( status) = self . file_progress_bars . lock ( ) . unwrap ( ) . get ( url) {
229- status. received_length ( content_len) ;
230- }
231- }
232-
233- /// Notifies self that data of size `len` has been received.
234- pub ( crate ) fn data_received ( & self , len : usize , url : & str ) {
235- let mut map = self . file_progress_bars . lock ( ) . unwrap ( ) ;
236- if let Some ( status) = map. get_mut ( url) {
237- status. received_data ( len) ;
238- } ;
239- }
240-
241- /// Notifies self that the download has finished.
242- pub ( crate ) fn download_finished ( & self , url : & str ) {
243- let map = self . file_progress_bars . lock ( ) . unwrap ( ) ;
244- if let Some ( status) = map. get ( url) {
245- status. finished ( )
246- } ;
247- }
248-
249- /// Notifies self that the download has failed.
250- pub ( crate ) fn download_failed ( & self , url : & str ) {
251- let map = self . file_progress_bars . lock ( ) . unwrap ( ) ;
252- if let Some ( status) = map. get ( url) {
253- status. failed ( ) ;
254- } ;
255- }
256-
257- /// Notifies self that the download is being retried.
258- pub ( crate ) fn retrying_download ( & self , url : & str ) {
259- let mut map = self . file_progress_bars . lock ( ) . unwrap ( ) ;
260- if let Some ( status) = map. get_mut ( url) {
261- status. retrying ( ) ;
262- } ;
216+ status
263217 }
264218}
265219
266- struct DownloadStatus {
220+ pub ( crate ) struct DownloadStatus {
267221 progress : ProgressBar ,
268- retry_time : Option < Instant > ,
222+ retry_time : Mutex < Option < Instant > > ,
269223}
270224
271225impl DownloadStatus {
272- fn new ( component : String ) -> Self {
226+ fn new ( component : impl Into < Cow < ' static , str > > ) -> Self {
273227 let progress = ProgressBar :: hidden ( ) ;
274228 progress. set_style (
275229 ProgressStyle :: with_template (
@@ -282,25 +236,23 @@ impl DownloadStatus {
282236
283237 Self {
284238 progress,
285- retry_time : None ,
239+ retry_time : Mutex :: new ( None ) ,
286240 }
287241 }
288242
289- fn received_length ( & self , len : u64 ) {
243+ pub ( crate ) fn received_length ( & self , len : u64 ) {
290244 self . progress . reset ( ) ;
291245 self . progress . set_length ( len) ;
292246 }
293247
294- fn received_data ( & mut self , len : usize ) {
248+ pub ( crate ) fn received_data ( & self , len : usize ) {
295249 self . progress . inc ( len as u64 ) ;
296- if !self
297- . retry_time
298- . is_some_and ( |instant| instant. elapsed ( ) > Duration :: from_secs ( 1 ) )
299- {
250+ let mut retry_time = self . retry_time . lock ( ) . unwrap ( ) ;
251+ if !retry_time. is_some_and ( |instant| instant. elapsed ( ) > Duration :: from_secs ( 1 ) ) {
300252 return ;
301253 }
302254
303- self . retry_time = None ;
255+ * retry_time = None ;
304256 self . progress . set_style (
305257 ProgressStyle :: with_template (
306258 "{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
@@ -310,24 +262,24 @@ impl DownloadStatus {
310262 ) ;
311263 }
312264
313- fn finished ( & self ) {
265+ pub ( crate ) fn finished ( & self ) {
314266 self . progress . set_style (
315267 ProgressStyle :: with_template ( "{msg:>12.bold} downloaded {total_bytes} in {elapsed}" )
316268 . unwrap ( ) ,
317269 ) ;
318270 self . progress . finish ( ) ;
319271 }
320272
321- fn failed ( & self ) {
273+ pub ( crate ) fn failed ( & self ) {
322274 self . progress . set_style (
323275 ProgressStyle :: with_template ( "{msg:>12.bold} download failed after {elapsed}" )
324276 . unwrap ( ) ,
325277 ) ;
326278 self . progress . finish ( ) ;
327279 }
328280
329- fn retrying ( & mut self ) {
330- self . retry_time = Some ( Instant :: now ( ) ) ;
281+ pub ( crate ) fn retrying ( & self ) {
282+ * self . retry_time . lock ( ) . unwrap ( ) = Some ( Instant :: now ( ) ) ;
331283 self . progress
332284 . set_style ( ProgressStyle :: with_template ( "{msg:>12.bold} retrying download" ) . unwrap ( ) ) ;
333285 }
0 commit comments