From ce7087b1076d3bf8de54ccaa6c0d76d0a684e36c Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 6 Feb 2022 11:59:21 +0100 Subject: [PATCH] Use thiserror for to derive Error --- Cargo.lock | 21 ++++++++++++++ Cargo.toml | 1 + src/error.rs | 79 ++++++++++++-------------------------------------- src/main.rs | 2 +- src/options.rs | 4 +-- 5 files changed, 43 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f62b91..23deba1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,6 +263,7 @@ dependencies = [ "shell-words", "statistical", "tempfile", + "thiserror", "winapi", ] @@ -819,6 +820,26 @@ dependencies = [ "terminal_size", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-xid" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index b8f81e1..528894a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ serde_json = "1.0" rust_decimal = "1.19" rand = "0.8" shell-words = "1.0" +thiserror = "1.0" [target.'cfg(not(windows))'.dependencies] libc = "0.2" diff --git a/src/error.rs b/src/error.rs index 279f337..1588dc8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,18 +1,24 @@ -use std::error::Error; -use std::fmt; use std::num; use std::num::ParseIntError; use rust_decimal::Error as DecimalError; +use thiserror::Error; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum ParameterScanError { + #[error("Error while parsing parameter scan arguments ({0})")] ParseIntError(num::ParseIntError), + #[error("Error while parsing parameter scan arguments ({0})")] ParseDecimalError(DecimalError), + #[error("Empty parameter range")] EmptyRange, + #[error("Parameter range is too large")] TooLarge, + #[error("Zero is not a valid parameter step")] ZeroStep, + #[error("A step size is required when the range bounds are floating point numbers. The step size can be specified with the '--parameter-step-size' parameter")] StepRequired, + #[error("'--command-name' has been specified {0} times. It has to appear exactly once, or exactly {1} times (number of benchmarks)")] UnexpectedCommandNameCount(usize, usize), } @@ -28,69 +34,20 @@ impl From for ParameterScanError { } } -impl fmt::Display for ParameterScanError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - ParameterScanError::ParseIntError(ref e) => write!(f, "{}", e), - ParameterScanError::ParseDecimalError(ref e) => write!(f, "{}", e), - ParameterScanError::EmptyRange => write!(f, "Empty parameter range"), - ParameterScanError::TooLarge => write!(f, "Parameter range is too large"), - ParameterScanError::ZeroStep => write!(f, "Zero is not a valid parameter step"), - ParameterScanError::StepRequired => write!( - f, - "A step size is required when the range bounds are \ - floating point numbers. The step size can be specified \ - with the '--parameter-step-size' parameter" - ), - ParameterScanError::UnexpectedCommandNameCount(real, expected) => { - write!( - f, - "'--command-name' has been specified {} times. It has to appear exactly once, or exactly {} times (number of benchmarks)", - real, expected - ) - } - } - } -} - -impl Error for ParameterScanError {} - -#[derive(Debug, PartialEq)] +#[derive(Debug, Error)] pub enum OptionsError<'a> { + #[error( + "Conflicting requirements for the number of runs (empty range, min is larger than max)" + )] EmptyRunsRange, + #[error("Too many --command-name options: Expected {0} at most")] TooManyCommandNames(usize), + #[error("'--command-name' has been specified {0} times. It has to appear exactly once, or exactly {1} times (number of benchmarks)")] UnexpectedCommandNameCount(usize, usize), + #[error("Could not read numeric argument to '--{0}': {1}")] NumericParsingError(&'a str, ParseIntError), + #[error("An empty command has been specified for the '--shell ' option")] EmptyShell, + #[error("Failed to parse '--shell ' expression as command line: {0}")] ShellParseError(shell_words::ParseError), } - -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"), - OptionsError::TooManyCommandNames(n) => { - write!(f, "Too many --command-name options: expected {} at most", n) - } - OptionsError::UnexpectedCommandNameCount(real, expected) => { - write!( - f, - "'--command-name' has been specified {} times. It has to appear exactly once, or exactly {} times (number of benchmarks)", - real, expected - ) - } - OptionsError::NumericParsingError(cmd, ref err) => write!( - f, - "Could not read numeric argument to '--{cmd}': {err}", - cmd = cmd, - err = err - ), - OptionsError::EmptyShell => write!(f, "Empty command at --shell option"), - OptionsError::ShellParseError(ref err) => { - write!(f, "Could not parse --shell value as command line: {}", err) - } - } - } -} - -impl<'a> Error for OptionsError<'a> {} diff --git a/src/main.rs b/src/main.rs index cf45f3f..d91f60c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -261,7 +261,7 @@ fn build_export_manager(matches: &ArgMatches) -> io::Result { } /// Build the commands to benchmark -fn build_commands(matches: &ArgMatches) -> Vec { +fn build_commands(matches: &ArgMatches) -> Result> { let command_names = matches.values_of("command-name"); let command_strings = matches.values_of("command").unwrap(); diff --git a/src/options.rs b/src/options.rs index 4906b4f..0cbd895 100644 --- a/src/options.rs +++ b/src/options.rs @@ -196,7 +196,7 @@ fn test_shell_parse_command() { OptionsError::ShellParseError(_) )); - assert_eq!(Shell::parse("").unwrap_err(), OptionsError::EmptyShell); + assert!(matches!(Shell::parse("").unwrap_err(), OptionsError::EmptyShell)); - assert_eq!(Shell::parse("''").unwrap_err(), OptionsError::EmptyShell); + assert!(matches!(Shell::parse("''").unwrap_err(), OptionsError::EmptyShell)); }