diff --git a/schemsearch-cli/src/main.rs b/schemsearch-cli/src/main.rs index 143bdb1..f17f263 100644 --- a/schemsearch-cli/src/main.rs +++ b/schemsearch-cli/src/main.rs @@ -94,7 +94,7 @@ fn main() { ) .arg( Arg::new("output") - .help("The output format and path [Format:Path] available formats: text, json, csv; available paths: std, (file path)") + .help("The output format and path [Format:Path] available formats: text, json, csv; available paths: std, err, (file path)") .short('o') .long("output") .action(ArgAction::Append) @@ -246,7 +246,11 @@ fn main() { ThreadPoolBuilder::new().num_threads(*matches.get_one::("threads").expect("Could not get threads")).build_global().unwrap(); - let matches: Vec = schematics.par_iter().progress_with_style(ProgressStyle::with_template("[{elapsed}, ETA: {eta}] {wide_bar} {pos}/{len} {per_sec}").unwrap()).map(|schem| { + let bar = ProgressBar::new(schematics.len() as u64); + bar.set_style(ProgressStyle::with_template("[{elapsed}, ETA: {eta}] {wide_bar} {pos}/{len} {per_sec}").unwrap()); + bar.set_draw_target(ProgressDrawTarget::stderr_with_hz(5)); + + let matches: Vec = schematics.par_iter().progress_with(bar).map(|schem| { match schem { SchematicSupplierType::PATH(schem) => { let schematic = match load_schem(&schem.path) { @@ -271,7 +275,7 @@ fn main() { } } Err(e) => { - println!("Error while loading schematic ({}): {}", schem.get_name(), e.to_string()); + eprintln!("Error while loading schematic ({}): {}", schem.get_name(), e.to_string()); SearchResult { name: schem.get_name(), matches: Vec::default() diff --git a/schemsearch-cli/src/sinks.rs b/schemsearch-cli/src/sinks.rs index c6f09a9..f42d4f5 100644 --- a/schemsearch-cli/src/sinks.rs +++ b/schemsearch-cli/src/sinks.rs @@ -2,12 +2,15 @@ use std::fs::File; use std::io::BufWriter; use std::str::FromStr; use std::io::Write; +use std::time::Duration; +use indicatif::HumanDuration; use schemsearch_lib::{Match, SearchBehavior}; use crate::json_output::{EndEvent, FoundEvent, InitEvent, JsonEvent}; #[derive(Debug, Clone)] pub enum OutputSink { Stdout, + Stderr, File(String), } @@ -37,6 +40,7 @@ impl FromStr for OutputSink { fn from_str(s: &str) -> Result { match s { "std" => Ok(OutputSink::Stdout), + "err" => OK(OutputSink::Stderr), _ => Ok(OutputSink::File(s.to_string())) } } @@ -46,6 +50,7 @@ impl OutputSink { pub fn output(&self) -> Box { match self { OutputSink::Stdout => Box::new(std::io::stdout().lock()), + OutputSink::Stderr => Box::new(std::io::stderr().lock()), OutputSink::File(path) => Box::new(BufWriter::new(File::create(path).unwrap())) } } @@ -77,7 +82,7 @@ impl OutputFormat { pub fn end(&self, end_time: u128) -> String { match self { - OutputFormat::Text => format!("Search complete in {}s\n", end_time / 1000), + OutputFormat::Text => format!("Search complete in {}\n", HumanDuration(Duration::from_millis(end_time as u64))), OutputFormat::CSV => format!("{}\n", end_time), OutputFormat::JSON => format!("{}\n", serde_json::to_string(&JsonEvent::End(EndEvent{ end_time })).unwrap()) }