From 46ad9bf39a84f8619492484c27376845e1084ce1 Mon Sep 17 00:00:00 2001 From: sharkdp Date: Fri, 16 Oct 2020 23:38:15 +0200 Subject: [PATCH] Show error if numeric arguments can not be parsed Shows an error message if the argument to options like '--warmup ' can not be parsed: > hyperfine --warmup xxx "sleep 1" Error: Could not read numeric argument to '--warmup': invalid digit found in string closes #337 --- CHANGELOG.md | 1 + src/hyperfine/error.rs | 14 +++++++++++--- src/main.rs | 17 +++++++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bfe473..7d9d337 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Fix a bug in the outlier detection which would only detect "slow outliers" but not the fast ones (runs that are much faster than the rest of the benchmarking runs), see #329 - Better error messages for very fast commands that would lead to inf/nan results in the relative speed comparison, see #319 +- Show error message if `--warmup` or `--*runs` arguments can not be parsed, see #337 - Keep output colorized when the output is not interactive and `--style=full` or `--style=color` is used. ## Other diff --git a/src/hyperfine/error.rs b/src/hyperfine/error.rs index dc1e310..994afbc 100644 --- a/src/hyperfine/error.rs +++ b/src/hyperfine/error.rs @@ -2,6 +2,7 @@ use rust_decimal::Error as DecimalError; use std::error::Error; use std::fmt; use std::num; +use std::num::ParseIntError; #[derive(Debug)] pub enum ParameterScanError { @@ -46,13 +47,14 @@ impl fmt::Display for ParameterScanError { impl Error for ParameterScanError {} #[derive(Debug)] -pub enum OptionsError { +pub enum OptionsError<'a> { RunsBelowTwo, EmptyRunsRange, TooManyCommandNames(usize), + NumericParsingError(&'a str, ParseIntError), } -impl fmt::Display for OptionsError { +impl<'a> fmt::Display for OptionsError<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { OptionsError::EmptyRunsRange => write!(f, "Empty runs range"), @@ -60,8 +62,14 @@ impl fmt::Display for OptionsError { OptionsError::TooManyCommandNames(n) => { write!(f, "Too many --command-name options: expected {} at most", n) } + OptionsError::NumericParsingError(cmd, ref err) => write!( + f, + "Could not read numeric argument to '--{cmd}': {err}", + cmd = cmd, + err = err + ), } } } -impl Error for OptionsError {} +impl<'a> Error for OptionsError<'a> {} diff --git a/src/main.rs b/src/main.rs index 45e929b..9ec5a60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,20 +86,25 @@ fn main() { } /// Build the HyperfineOptions that correspond to the given ArgMatches -fn build_hyperfine_options(matches: &ArgMatches<'_>) -> Result { +fn build_hyperfine_options<'a>( + matches: &ArgMatches<'a>, +) -> Result> { let mut options = HyperfineOptions::default(); let param_to_u64 = |param| { matches .value_of(param) - .and_then(|n| u64::from_str_radix(n, 10).ok()) + .map(|n| { + u64::from_str_radix(n, 10).map_err(|e| OptionsError::NumericParsingError(param, e)) + }) + .transpose() }; - options.warmup_count = param_to_u64("warmup").unwrap_or(options.warmup_count); + options.warmup_count = param_to_u64("warmup")?.unwrap_or(options.warmup_count); - let mut min_runs = param_to_u64("min-runs"); - let mut max_runs = param_to_u64("max-runs"); + let mut min_runs = param_to_u64("min-runs")?; + let mut max_runs = param_to_u64("max-runs")?; - if let Some(runs) = param_to_u64("runs") { + if let Some(runs) = param_to_u64("runs")? { min_runs = Some(runs); max_runs = Some(runs); }