Skip to content

Commit

Permalink
command: return Box<dyn Error> from Argument.parse()
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgrinaker committed May 23, 2024
1 parent eb25a24 commit 44df27d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Unreleased

**Breaking changes**

* Return `Box<dyn Error>` from `Argument.parse()`, like `Runner` does.

**Improvements**

* Add `Command.pos_args()` and `key_args()` for filtering argument types.
Expand Down
33 changes: 18 additions & 15 deletions src/command.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::error::Error;

/// A block, consisting of multiple commands.
#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -55,14 +56,14 @@ pub struct Argument {

impl Argument {
/// Parses the argument value as a T using core::str::parse(). Convenience
/// method that returns a string error to ease error handling in a
/// [`Runner`](crate::Runner).
pub fn parse<T>(&self) -> Result<T, String>
/// method that returns an improved error message as a boxed error to ease
/// error handling in a [`Runner`](crate::Runner).
pub fn parse<T>(&self) -> Result<T, Box<dyn Error>>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: std::fmt::Display,
{
self.value.parse().map_err(|e| format!("invalid argument '{}': {e}", self.value))
self.value.parse().map_err(|e| format!("invalid argument '{}': {e}", self.value).into())
}
}

Expand Down Expand Up @@ -126,23 +127,25 @@ mod tests {
/// to core::str::parse().
#[test]
fn argument_parse() {
assert_eq!(arg!("-1").parse(), Ok(-1_i64));
assert_eq!(arg!("0").parse(), Ok(0_i64));
assert_eq!(arg!("1").parse(), Ok(1_i64));
assert_eq!(arg!("-1").parse::<i64>().unwrap(), -1_i64);
assert_eq!(arg!("0").parse::<i64>().unwrap(), 0_i64);
assert_eq!(arg!("1").parse::<i64>().unwrap(), 1_i64);

assert_eq!(
arg!("").parse::<i64>(),
Err("invalid argument '': cannot parse integer from empty string".to_string())
arg!("").parse::<i64>().unwrap_err().to_string(),
"invalid argument '': cannot parse integer from empty string"
);
assert_eq!(
arg!("foo").parse::<i64>(),
Err("invalid argument 'foo': invalid digit found in string".to_string())
arg!("foo").parse::<i64>().unwrap_err().to_string(),
"invalid argument 'foo': invalid digit found in string"
);

assert_eq!(arg!("false").parse(), Ok(false));
assert_eq!(arg!("true").parse(), Ok(true));
assert!(!arg!("false").parse::<bool>().unwrap());
assert!(arg!("true").parse::<bool>().unwrap());

assert_eq!(
arg!("").parse::<bool>(),
Err("invalid argument '': provided string was not `true` or `false`".to_string())
arg!("").parse::<bool>().unwrap_err().to_string(),
"invalid argument '': provided string was not `true` or `false`"
);
}
}

0 comments on commit 44df27d

Please sign in to comment.