@@ -27,7 +27,7 @@ use std::fmt;
2727use sysexits:: ExitCode ;
2828use tabled:: settings:: object:: Rows ;
2929
30- use std :: io :: { self , Write } ;
30+ use indicatif :: { ProgressBar , ProgressStyle } ;
3131use tabled:: settings:: { Panel , Remove , Style } ;
3232use tabled:: {
3333 Table , Tabled ,
@@ -467,131 +467,123 @@ pub trait ProgressReporter {
467467
468468#[ allow( dead_code) ]
469469pub struct InteractiveProgressReporter {
470- operation_name : String ,
470+ bar : Option < ProgressBar > ,
471471 failures : usize ,
472- current_position : usize ,
473- total : usize ,
474- results : Vec < char > ,
475472}
476473
477474#[ allow( dead_code) ]
478475impl InteractiveProgressReporter {
479476 pub fn new ( ) -> Self {
480477 Self {
481- operation_name : String :: new ( ) ,
478+ bar : None ,
482479 failures : 0 ,
483- current_position : 0 ,
484- total : 0 ,
485- results : Vec :: new ( ) ,
486480 }
487481 }
488482}
489483
490484impl ProgressReporter for InteractiveProgressReporter {
491485 fn start_operation ( & mut self , total : usize , operation_name : & str ) {
492- self . operation_name = operation_name. to_string ( ) ;
486+ let bar = ProgressBar :: new ( total as u64 ) ;
487+ bar. set_style (
488+ ProgressStyle :: with_template (
489+ "{msg} [{bar:40.cyan/blue}] {pos}/{len} ({percent}%) {elapsed_precise}" ,
490+ )
491+ . unwrap ( ) ,
492+ ) ;
493+ bar. set_message ( operation_name. to_string ( ) ) ;
494+ self . bar = Some ( bar) ;
493495 self . failures = 0 ;
494- self . current_position = 0 ;
495- self . total = total;
496- self . results = vec ! [ '.' ; total] ;
497- println ! ( "{}..." , operation_name) ;
498496 }
499497
500498 fn report_progress ( & mut self , _current : usize , _total : usize , _item_name : & str ) {
501- if self . current_position < self . results . len ( ) {
502- self . results [ self . current_position ] = '#' ;
499+ if let Some ( bar ) = & self . bar {
500+ bar . inc ( 1 ) ;
503501 }
504- self . current_position += 1 ;
505- let percentage = if self . total > 0 {
506- ( self . current_position * 100 ) / self . total
507- } else {
508- 0
509- } ;
510- let bar: String = self . results . iter ( ) . collect ( ) ;
511- print ! ( "\r Progress: [{:3}%] [{}]" , percentage, bar) ;
512- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
513502 }
514503
515504 fn report_success ( & mut self , _item_name : & str ) {
516- // No-op: progress bar already shows the advancement
505+ // No-op: progress already incremented in report_progress
517506 }
518507
519508 fn report_skip ( & mut self , _item_name : & str , _reason : & str ) {
520- // No-op: progress bar already shows the advancement
509+ // No-op: progress already incremented in report_progress
521510 }
522511
523512 fn report_failure ( & mut self , _item_name : & str , _error : & str ) {
524513 self . failures += 1 ;
525- if self . current_position < self . results . len ( ) {
526- self . results [ self . current_position ] = 'X' ;
514+ if let Some ( bar ) = & self . bar {
515+ bar . inc ( 1 ) ;
527516 }
528- self . current_position += 1 ;
529- let percentage = if self . total > 0 {
530- ( self . current_position * 100 ) / self . total
531- } else {
532- 0
533- } ;
534- let bar: String = self . results . iter ( ) . collect ( ) ;
535- print ! ( "\r Progress: [{:3}%] [{}]" , percentage, bar) ;
536- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
537517 }
538518
539519 fn finish_operation ( & mut self , total : usize ) {
540- let successes = total - self . failures ;
541- if self . failures == 0 {
542- println ! ( "\n ✅ Completed: {} items processed successfully" , total) ;
543- } else if successes == 0 {
544- println ! ( "\n ❌ Failed: All {} items failed to process" , total) ;
545- } else {
546- println ! (
547- "\n ⚠️ Completed with failures: {} succeeded, {} failed out of {} total" ,
548- successes, self . failures, total
549- ) ;
520+ if let Some ( bar) = & self . bar {
521+ bar. finish ( ) ;
522+
523+ let successes = total - self . failures ;
524+ if self . failures == 0 {
525+ println ! ( "✅ Completed: {} items processed successfully" , total) ;
526+ } else if successes == 0 {
527+ println ! ( "❌ Failed: All {} items failed to process" , total) ;
528+ } else {
529+ println ! (
530+ "⚠️ Completed with failures: {} succeeded, {} failed out of {} total" ,
531+ successes, self . failures, total
532+ ) ;
533+ }
550534 }
535+ self . bar = None ;
551536 }
552537}
553538
554539#[ allow( dead_code) ]
555540pub struct NonInteractiveProgressReporter {
556- operation_name : String ,
541+ bar : Option < ProgressBar > ,
557542}
558543
559544#[ allow( dead_code) ]
560545impl NonInteractiveProgressReporter {
561546 pub fn new ( ) -> Self {
562- Self {
563- operation_name : String :: new ( ) ,
564- }
547+ Self { bar : None }
565548 }
566549}
567550
568551impl ProgressReporter for NonInteractiveProgressReporter {
569- fn start_operation ( & mut self , _total : usize , operation_name : & str ) {
570- self . operation_name = operation_name. to_string ( ) ;
571- print ! ( "{}: " , operation_name) ;
572- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
552+ fn start_operation ( & mut self , total : usize , operation_name : & str ) {
553+ let bar = ProgressBar :: new ( total as u64 ) ;
554+ bar. set_style (
555+ ProgressStyle :: with_template ( "{msg}: {pos}/{len} [{elapsed_precise}]" ) . unwrap ( ) ,
556+ ) ;
557+ bar. set_message ( operation_name. to_string ( ) ) ;
558+ self . bar = Some ( bar) ;
573559 }
574560
575561 fn report_progress ( & mut self , _current : usize , _total : usize , _item_name : & str ) {
576- print ! ( "." ) ;
577- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
562+ if let Some ( bar) = & self . bar {
563+ bar. inc ( 1 ) ;
564+ }
578565 }
579566
580567 fn report_success ( & mut self , _item_name : & str ) {
581- // Hash already printed in report_progress
568+ // No-op: progress already incremented in report_progress
582569 }
583570
584571 fn report_skip ( & mut self , _item_name : & str , _reason : & str ) {
585- // Hash already printed in report_progress
572+ // No-op: progress already incremented in report_progress
586573 }
587574
588575 fn report_failure ( & mut self , _item_name : & str , _error : & str ) {
589- print ! ( "x" ) ;
590- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
576+ if let Some ( bar) = & self . bar {
577+ bar. inc ( 1 ) ;
578+ }
591579 }
592580
593581 fn finish_operation ( & mut self , total : usize ) {
594- println ! ( "\n Completed: {} items processed" , total) ;
582+ if let Some ( bar) = & self . bar {
583+ bar. finish ( ) ;
584+ println ! ( "Completed: {} items processed" , total) ;
585+ }
586+ self . bar = None ;
595587 }
596588}
597589
0 commit comments