Skip to content

Commit

Permalink
Add StructOpt::from_iter_safe method (#98)
Browse files Browse the repository at this point in the history
I would like to be able to test argument parsing, which requires an error
value, not a `process::exit()`.
  • Loading branch information
quodlibetor authored and TeXitoi committed Apr 20, 2018
1 parent be85438 commit ccb04a3
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# NEXT

* Add `StructOpt::from_iter_safe()`, which returns an `Error` instead of
killing the program when it fails to parse, or parses one of the
short-circuiting flags. ([#98](https://github.com/TeXitoi/structopt/pull/98)
by [@quodlibetor](https://github.com/quodlibetor))

# v0.2.7 (2018-04-12)

* Add flattening, the insertion of options of another StructOpt struct into another ([#92](https://github.com/TeXitoi/structopt/pull/92)) by [@birkenfeld](https://github.com/birkenfeld)
Expand Down
14 changes: 14 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,4 +425,18 @@ pub trait StructOpt {
{
Self::from_clap(&Self::clap().get_matches_from(iter))
}

/// Gets the struct from any iterator such as a `Vec` of your making.
///
/// Returns a `clap::Error` in case of failure. This does *not* exit in the
/// case of `--help` or `--version`, to achieve the same behavior as
/// `from_iter()` you must call `.exit()` on the error value.
fn from_iter_safe<I>(iter: I) -> Result<Self, clap::Error>
where
Self: Sized,
I: IntoIterator,
I::Item: Into<OsString> + Clone
{
Ok(Self::from_clap(&Self::clap().get_matches_from_safe(iter)?))
}
}
18 changes: 18 additions & 0 deletions tests/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
extern crate structopt;

use structopt::StructOpt;
use structopt::clap;

#[test]
fn required_argument() {
Expand Down Expand Up @@ -67,3 +68,20 @@ fn arguments() {
assert_eq!(Opt { arg: vec![] }, Opt::from_iter(&["test"]));
assert_eq!(Opt { arg: vec![24, 42] }, Opt::from_iter(&["test", "24", "42"]));
}


#[test]
fn arguments_safe() {
#[derive(StructOpt, PartialEq, Debug)]
struct Opt {
arg: Vec<i32>,
}
assert_eq!(Opt { arg: vec![24] }, Opt::from_iter_safe(&["test", "24"]).unwrap());
assert_eq!(Opt { arg: vec![] }, Opt::from_iter_safe(&["test"]).unwrap());
assert_eq!(Opt { arg: vec![24, 42] }, Opt::from_iter_safe(&["test", "24", "42"]).unwrap());

assert_eq!(
clap::ErrorKind::ValueValidation,
Opt::from_iter_safe(&["test", "NOPE"]).err().unwrap().kind,
);
}

0 comments on commit ccb04a3

Please sign in to comment.