@@ -12,6 +12,7 @@ use std::{
12
12
io,
13
13
path:: { Path , PathBuf } ,
14
14
str:: FromStr ,
15
+ time:: Instant ,
15
16
} ;
16
17
use structopt:: StructOpt ;
17
18
use strum;
@@ -81,7 +82,18 @@ fn main() -> CliResult {
81
82
//
82
83
// We keep this in top level scope, since we want the progress bar to live during the whole
83
84
// program execution, so it will be displayed.
84
- let progress_bar;
85
+ let progress_bar = if args. input . is_file ( ) && ( args. output . is_file ( ) || isnt ( Stream :: Stdout ) ) {
86
+ let progress_bar = ProgressBar :: new ( 0 ) ;
87
+ let fmt = "{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})" ;
88
+ progress_bar. set_style (
89
+ ProgressStyle :: default_bar ( )
90
+ . template ( fmt)
91
+ . progress_chars ( "#>-" ) ,
92
+ ) ;
93
+ Some ( progress_bar)
94
+ } else {
95
+ None
96
+ } ;
85
97
86
98
// Keep our reference to stdin alive, if need be. Only initialized if we don't read from a file
87
99
// and read from stdin. We hold it alive at top level scop, so we can hold the lock to it, for
@@ -93,6 +105,9 @@ fn main() -> CliResult {
93
105
// file, we open in this code).
94
106
let std_out;
95
107
108
+ // Initial time measurement
109
+ let initial_time = Instant :: now ( ) ;
110
+
96
111
let input: Box < dyn io:: Read > = match args. input {
97
112
IoArg :: File ( input) => {
98
113
// Path argument specified. Open file and initialize progress bar.
@@ -104,15 +119,9 @@ fn main() -> CliResult {
104
119
// progress bar.
105
120
// * We don't want the Progress bar to interfere with the output, if writing to /dev/tty.
106
121
// Progress bar interferes with formatting if stdout and stderr both go to /dev/tty
107
- if args . output . is_file ( ) || isnt ( Stream :: Stdout ) {
122
+ if let Some ( progress_bar ) = & progress_bar {
108
123
let len = file. metadata ( ) ?. len ( ) ;
109
- progress_bar = ProgressBar :: new ( len) ;
110
- let fmt = "{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})" ;
111
- progress_bar. set_style (
112
- ProgressStyle :: default_bar ( )
113
- . template ( fmt)
114
- . progress_chars ( "#>-" ) ,
115
- ) ;
124
+ progress_bar. set_length ( len) ;
116
125
let file_with_pbar = progress_bar. wrap_read ( file) ;
117
126
118
127
if has_gz_extension ( & input) {
@@ -156,7 +165,11 @@ fn main() -> CliResult {
156
165
Box :: new ( writer)
157
166
}
158
167
} ;
159
- generate_xml ( & mut out, reader, & args. category , args. record_type ) ?;
168
+ let num_records = generate_xml ( & mut out, reader, & args. category , args. record_type ) ?;
169
+ // Drop progress bar, so it's removed from stderr before we print the performance metrics.
170
+ // Otherwise, the drop handler would erroneously remove the lower lines of the performance metrics output.
171
+ std:: mem:: drop ( progress_bar) ;
172
+ print_performance_metrics ( & initial_time, num_records) ;
160
173
Ok ( ( ) )
161
174
}
162
175
@@ -167,3 +180,11 @@ fn has_gz_extension(path: &Path) -> bool {
167
180
_ => false ,
168
181
}
169
182
}
183
+
184
+ fn print_performance_metrics ( initial_time : & Instant , num_records : u64 ) {
185
+ eprintln ! (
186
+ "Processed {} records in {}." ,
187
+ num_records,
188
+ humantime:: format_duration( initial_time. elapsed( ) )
189
+ ) ;
190
+ }
0 commit comments