From 5e20a29b4fdc8a2d442d1093681b396dcb4b816b Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 7 Jan 2020 11:18:04 +0000 Subject: Add structopt dependency in version 0.3.7 This patch series replaces argparse with structopt in the argument handling code. As a first step, we need structopt as a dependency. Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296 Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7 Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1 Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2 Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3 Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2 Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3 Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393 Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7 --- clap/examples/14_groups.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 clap/examples/14_groups.rs (limited to 'clap/examples/14_groups.rs') diff --git a/clap/examples/14_groups.rs b/clap/examples/14_groups.rs new file mode 100644 index 0000000..e160464 --- /dev/null +++ b/clap/examples/14_groups.rs @@ -0,0 +1,87 @@ +/// `ArgGroup`s are a family of related arguments and way for you to say, "Any of these arguments". +/// By placing arguments in a logical group, you can make easier requirement and exclusion rules +/// instead of having to list each individually, or when you want a rule to apply "any but not all" +/// arguments. +/// +/// For instance, you can make an entire `ArgGroup` required, this means that one (and *only* one) +/// argument from that group must be present. Using more than one argument from an `ArgGroup` causes +/// a failure (graceful exit). +/// +/// You can also do things such as name an `ArgGroup` as a confliction or requirement, meaning any +/// of the arguments that belong to that group will cause a failure if present, or must present +/// respectively. +/// +/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be +/// present out of a given set. Imagine that you had multiple arguments, and you want one of them to +/// be required, but making all of them required isn't feasible because perhaps they conflict with +/// each other. For example, lets say that you were building an application where one could set a +/// given version number by supplying a string with an option argument, i.e. `--set-ver v1.2.3`, you +/// also wanted to support automatically using a previous version number and simply incrementing one +/// of the three numbers. So you create three flags `--major`, `--minor`, and `--patch`. All of +/// these arguments shouldn't be used at one time but you want to specify that *at least one* of +/// them is used. For this, you can create a group. + +extern crate clap; + +use clap::{App, Arg, ArgGroup}; + +fn main() { + // Create application like normal + let matches = App::new("myapp") + // Add the version arguments + .args_from_usage("--set-ver [ver] 'set version manually' + --major 'auto inc major' + --minor 'auto inc minor' + --patch 'auto inc patch'") + // Create a group, make it required, and add the above arguments + .group(ArgGroup::with_name("vers") + .required(true) + .args(&["ver", "major", "minor", "patch"])) + // Arguments can also be added to a group individually, these two arguments + // are part of the "input" group which is not required + .arg(Arg::from_usage("[INPUT_FILE] 'some regular input'") + .group("input")) + .arg(Arg::from_usage("--spec-in [SPEC_IN] 'some special input argument'") + .group("input")) + // Now let's assume we have a -c [config] argument which requires one of + // (but **not** both) the "input" arguments + .arg(Arg::with_name("config") + .short("c") + .takes_value(true) + .requires("input")) + .get_matches(); + + // Let's assume the old version 1.2.3 + let mut major = 1; + let mut minor = 2; + let mut patch = 3; + + // See if --set-ver was used to set the version manually + let version = if let Some(ver) = matches.value_of("ver") { + format!("{}", ver) + } else { + // Increment the one requested (in a real program, we'd reset the lower numbers) + let (maj, min, pat) = (matches.is_present("major"), + matches.is_present("minor"), + matches.is_present("patch")); + match (maj, min, pat) { + (true, _, _) => major += 1, + (_, true, _) => minor += 1, + (_, _, true) => patch += 1, + _ => unreachable!(), + }; + format!("{}.{}.{}", major, minor, patch) + }; + + println!("Version: {}", version); + + // Check for usage of -c + if matches.is_present("config") { + let input = matches.value_of("INPUT_FILE").unwrap_or(matches.value_of("SPEC_IN").unwrap()); + println!("Doing work using input {} and config {}", + input, + matches.value_of("config").unwrap()); + } + + +} -- cgit v1.2.1