Skip to content

Commit bd97ce7

Browse files
Stephan Heßelmann (lgtf/39809)pacman82
Stephan Heßelmann (lgtf/39809)
authored andcommitted
Add performance metrics.
1 parent 5175513 commit bd97ce7

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

Cargo.lock

+8-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ structopt = "0.3.12"
2020
quick-xml = "0.18.1"
2121
flate2 = "1.0.14"
2222
atty = "0.2.14"
23+
humantime = "2.0.0"
2324

2425
[dev-dependencies]
2526
tempfile = "3.1.0"

src/generate_xml.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ use std::io::{self, Read, Write};
1414
/// extensions are placed within a `CustomerExtension` tag in within the record. `category` is used
1515
/// for the root tag name. `record_type` switches between `<Record>`, `<DeleteRecord>` and
1616
/// `<DeleteAllRecords>` in markup.
17+
///
18+
/// # Return
19+
///
20+
/// Number of processed records.
1721
pub fn generate_xml<O: Write, I: Read>(
1822
out: O,
1923
mut reader: CsvSource<I>,
2024
category: &str,
2125
record_type: RecordType,
22-
) -> io::Result<()> {
26+
) -> io::Result<u64> {
2327
let mut writer = Writer::new_with_indent(out, b'\t', 1);
2428
// Write declaration
2529
// <?xml version="1.0" encoding="UTF-8" ?>
@@ -28,13 +32,15 @@ pub fn generate_xml<O: Write, I: Read>(
2832
.map_err(expect_io_error)?;
2933
// Open root tag (Category)
3034
open_markup(&mut writer, category)?;
35+
let mut num_records: u64 = 0;
3136
while let Some(record) = reader.read_record()? {
3237
// Write one record for each entry in csv
3338
write_record(&mut writer, &record, record_type.as_str())?;
39+
num_records += 1;
3440
}
3541
// Close root tag (Category)
3642
close_markup(&mut writer, category)?;
37-
Ok(())
43+
Ok(num_records)
3844
}
3945

4046
/// Unwraps io::error, panics if the it is not `quick_xml::Error::Io`

src/main.rs

+31-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::{
1212
io,
1313
path::{Path, PathBuf},
1414
str::FromStr,
15+
time::Instant,
1516
};
1617
use structopt::StructOpt;
1718
use strum;
@@ -81,7 +82,18 @@ fn main() -> CliResult {
8182
//
8283
// We keep this in top level scope, since we want the progress bar to live during the whole
8384
// 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+
};
8597

8698
// Keep our reference to stdin alive, if need be. Only initialized if we don't read from a file
8799
// 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 {
93105
// file, we open in this code).
94106
let std_out;
95107

108+
// Initial time measurement
109+
let initial_time = Instant::now();
110+
96111
let input: Box<dyn io::Read> = match args.input {
97112
IoArg::File(input) => {
98113
// Path argument specified. Open file and initialize progress bar.
@@ -104,15 +119,9 @@ fn main() -> CliResult {
104119
// progress bar.
105120
// * We don't want the Progress bar to interfere with the output, if writing to /dev/tty.
106121
// 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 {
108123
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);
116125
let file_with_pbar = progress_bar.wrap_read(file);
117126

118127
if has_gz_extension(&input) {
@@ -156,7 +165,11 @@ fn main() -> CliResult {
156165
Box::new(writer)
157166
}
158167
};
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);
160173
Ok(())
161174
}
162175

@@ -167,3 +180,11 @@ fn has_gz_extension(path: &Path) -> bool {
167180
_ => false,
168181
}
169182
}
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

Comments
 (0)