Skip to content

Commit

Permalink
Merge pull request #3752 from epage/panic
Browse files Browse the repository at this point in the history
fix(parser): Improve panic messages for get_one, etc
  • Loading branch information
epage committed May 25, 2022
2 parents ef3121c + a1df333 commit a9b3acf
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
24 changes: 23 additions & 1 deletion src/parser/error.rs
@@ -1,3 +1,5 @@
use crate::util::Id;

/// Violation of [`ArgMatches`][crate::ArgMatches] assumptions
#[derive(Clone, Debug, PartialEq, Eq)]
#[allow(missing_copy_implementations)] // We might add non-Copy types in the future
Expand All @@ -18,13 +20,33 @@ pub enum MatchesError {
},
}

impl MatchesError {
#[track_caller]
pub(crate) fn unwrap<T>(id: &Id, r: Result<T, MatchesError>) -> T {
let err = match r {
Ok(t) => {
return t;
}
Err(err) => err,
};
panic!(
"Mismatch between definition and access of `{:?}`. {}",
id, err
)
}
}

impl std::error::Error for MatchesError {}

impl std::fmt::Display for MatchesError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Downcast { actual, expected } => {
writeln!(f, "Could not downcast from {:?} to {:?}", actual, expected)
writeln!(
f,
"Could not downcast to {:?}, need to downcast to {:?}",
expected, actual
)
}
Self::UnknownArgument {} => {
writeln!(f, "Unknown argument or group id. Make sure you are using the argument id and not the short or long flags")
Expand Down
26 changes: 13 additions & 13 deletions src/parser/matches/arg_matches.rs
Expand Up @@ -122,8 +122,8 @@ impl ArgMatches {
/// [`occurrences_of`]: crate::ArgMatches::occurrences_of()
#[track_caller]
pub fn get_one<T: Any + Clone + Send + Sync + 'static>(&self, name: &str) -> Option<&T> {
self.try_get_one(name)
.expect("caller error: argument definition and access must match")
let id = Id::from(name);
MatchesError::unwrap(&id, self.try_get_one(name))
}

/// Iterate over values of a specific option or positional argument.
Expand Down Expand Up @@ -163,8 +163,8 @@ impl ArgMatches {
&self,
name: &str,
) -> Option<ValuesRef<T>> {
self.try_get_many(name)
.expect("caller error: argument definition and access must match")
let id = Id::from(name);
MatchesError::unwrap(&id, self.try_get_many(name))
}

/// Iterate over the original argument values.
Expand Down Expand Up @@ -208,9 +208,9 @@ impl ArgMatches {
/// [`OsSt`]: std::ffi::OsStr
/// [values]: OsValues
/// [`String`]: std::string::String
pub fn get_raw<T: Key>(&self, id: T) -> Option<RawValues<'_>> {
self.try_get_raw(id)
.expect("caller error: argument definition and access must match")
pub fn get_raw(&self, name: &str) -> Option<RawValues<'_>> {
let id = Id::from(name);
MatchesError::unwrap(&id, self.try_get_raw(name))
}

/// Returns the value of a specific option or positional argument.
Expand Down Expand Up @@ -250,8 +250,8 @@ impl ArgMatches {
/// [`default_value`]: crate::Arg::default_value()
/// [`occurrences_of`]: crate::ArgMatches::occurrences_of()
pub fn remove_one<T: Any + Clone + Send + Sync + 'static>(&mut self, name: &str) -> Option<T> {
self.try_remove_one(name)
.expect("caller error: argument definition and access must match")
let id = Id::from(name);
MatchesError::unwrap(&id, self.try_remove_one(name))
}

/// Return values of a specific option or positional argument.
Expand Down Expand Up @@ -288,8 +288,8 @@ impl ArgMatches {
&mut self,
name: &str,
) -> Option<Values2<T>> {
self.try_remove_many(name)
.expect("caller error: argument definition and access must match")
let id = Id::from(name);
MatchesError::unwrap(&id, self.try_remove_many(name))
}

/// Check if any args were present on the command line
Expand Down Expand Up @@ -1427,8 +1427,8 @@ impl ArgMatches {
}

/// Non-panicking version of [`ArgMatches::get_raw`]
pub fn try_get_raw<T: Key>(&self, id: T) -> Result<Option<RawValues<'_>>, MatchesError> {
let id = Id::from(id);
pub fn try_get_raw(&self, name: &str) -> Result<Option<RawValues<'_>>, MatchesError> {
let id = Id::from(name);
let arg = match self.try_get_arg(&id)? {
Some(arg) => arg,
None => return Ok(None),
Expand Down

0 comments on commit a9b3acf

Please sign in to comment.