@@ -23,12 +23,41 @@ pub mod util;
2323#[ cfg( test) ]
2424mod tests;
2525
26+ #[ derive( Debug , Clone ) ]
27+ pub enum FailReason {
28+ BadSize { expected : u64 , actual : u64 } ,
29+ BadHash { expected : String , actual : String } ,
30+ Missing ,
31+ }
32+ impl std:: fmt:: Display for FailReason {
33+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
34+ match self {
35+ FailReason :: BadSize { expected, actual } => {
36+ write ! ( f, "Bad size: {} (disk) vs {} (manifest)" , actual, expected)
37+ }
38+ FailReason :: BadHash { expected, actual } => {
39+ write ! ( f, "Bad hash: {} (disk) vs {} (manifest)" , actual, expected)
40+ }
41+ FailReason :: Missing => write ! ( f, "File missing" ) ,
42+ }
43+ }
44+ }
45+ impl std:: error:: Error for FailReason { }
46+
2647#[ derive( Debug ) ]
2748pub enum ItemProgress {
28- Downloading ( u64 , u64 ) , // bytes downloaded, total bytes
49+ Downloading {
50+ bytes_downloaded : u64 ,
51+ total_bytes : u64 ,
52+ } ,
2953 Validating ,
30- Completed ( u64 ) , // total bytes
31- Failed ,
54+ Passed {
55+ item_size : u64 ,
56+ } ,
57+ Failed {
58+ item_size : u64 ,
59+ reason : FailReason ,
60+ } ,
3261}
3362
3463// uuid, item name, progress
@@ -543,7 +572,7 @@ impl BundleInfo {
543572 let file_name = util:: get_file_name_without_parent ( file_path) ;
544573 let mut file_info = FileInfo :: build_file ( file_path) ;
545574 let mut attempts = 0 ;
546- while let Err ( e ) = {
575+ while let Err ( fail_reason ) = {
547576 if let Some ( ref cb) = callback {
548577 let uuid = version_uuid. unwrap_or_default ( ) ;
549578 cb ( & uuid, file_name, ItemProgress :: Validating ) ;
@@ -554,19 +583,33 @@ impl BundleInfo {
554583 let Some ( url) = download_url else {
555584 if let Some ( ref cb) = callback {
556585 let uuid = version_uuid. unwrap_or_default ( ) ;
557- cb ( & uuid, file_name, ItemProgress :: Failed ) ;
586+ cb (
587+ & uuid,
588+ file_name,
589+ ItemProgress :: Failed {
590+ item_size : self . compressed_info . size ,
591+ reason : fail_reason. clone ( ) ,
592+ } ,
593+ ) ;
558594 }
559- return Err ( e . into ( ) ) ;
595+ return Err ( fail_reason . clone ( ) . into ( ) ) ;
560596 } ;
561597
562598 if attempts >= MAX_DOWNLOAD_ATTEMPTS {
563599 if let Some ( ref cb) = callback {
564600 let uuid = version_uuid. unwrap_or_default ( ) ;
565- cb ( & uuid, file_name, ItemProgress :: Failed ) ;
601+ cb (
602+ & uuid,
603+ file_name,
604+ ItemProgress :: Failed {
605+ item_size : self . compressed_info . size ,
606+ reason : fail_reason. clone ( ) ,
607+ } ,
608+ ) ;
566609 }
567610 return Err ( format ! (
568611 "Failed to download {} after {} attempts: {}" ,
569- file_path, attempts, e
612+ file_path, attempts, fail_reason
570613 )
571614 . into ( ) ) ;
572615 }
@@ -586,7 +629,9 @@ impl BundleInfo {
586629 cb (
587630 & uuid,
588631 file_name,
589- ItemProgress :: Completed ( self . compressed_info . size ) ,
632+ ItemProgress :: Passed {
633+ item_size : self . compressed_info . size ,
634+ } ,
590635 ) ;
591636 }
592637 Ok ( attempts > 0 )
@@ -597,7 +642,7 @@ impl BundleInfo {
597642 folder_path : & str ,
598643 version_uuid : Option < Uuid > ,
599644 callback : Option < ProgressCallback > ,
600- ) -> Result < Vec < ( String , String ) > , Error > {
645+ ) -> Result < Vec < ( String , FailReason ) > , Error > {
601646 let uuid = version_uuid. unwrap_or_default ( ) ;
602647 let folder_path_leaf = util:: get_file_name_without_parent ( folder_path) ;
603648 let mut corrupted = Vec :: new ( ) ;
@@ -610,11 +655,16 @@ impl BundleInfo {
610655 cb ( & uuid, & file_id, ItemProgress :: Validating ) ;
611656 }
612657
613- let mut result = ItemProgress :: Completed ( file_info_good. size ) ;
614- if let Err ( e) = file_info. validate ( file_info_good) {
615- warn ! ( "{} invalid: {}" , file_id, e) ;
616- corrupted. push ( ( file_id. clone ( ) , e) ) ;
617- result = ItemProgress :: Failed ;
658+ let mut result = ItemProgress :: Passed {
659+ item_size : file_info_good. size ,
660+ } ;
661+ if let Err ( fail_reason) = file_info. validate ( file_info_good) {
662+ warn ! ( "{} invalid: {}" , file_id, fail_reason) ;
663+ corrupted. push ( ( file_id. clone ( ) , fail_reason. clone ( ) ) ) ;
664+ result = ItemProgress :: Failed {
665+ item_size : file_info_good. size ,
666+ reason : fail_reason,
667+ } ;
618668 }
619669
620670 if let Some ( ref cb) = callback {
@@ -662,19 +712,19 @@ impl FileInfo {
662712 Self { hash, size }
663713 }
664714
665- fn validate ( & self , good : & Self ) -> Result < ( ) , String > {
715+ fn validate ( & self , good : & Self ) -> Result < ( ) , FailReason > {
666716 if self . size != good. size {
667- return Err ( format ! (
668- "Bad size: {} (disk) vs {} (manifest)" ,
669- self . size, good . size
670- ) ) ;
717+ return Err ( FailReason :: BadSize {
718+ expected : good . size ,
719+ actual : self . size ,
720+ } ) ;
671721 }
672722
673723 if self . hash != good. hash {
674- return Err ( format ! (
675- "Bad hash: {} (disk) vs {} (manifest)" ,
676- self . hash, good . hash
677- ) ) ;
724+ return Err ( FailReason :: BadHash {
725+ expected : good . hash . clone ( ) ,
726+ actual : self . hash . clone ( ) ,
727+ } ) ;
678728 }
679729
680730 Ok ( ( ) )
0 commit comments