mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 23:37:32 +00:00
docs: updating docs for 2x release
This commit is contained in:
parent
609c06e119
commit
f1876388a7
19 changed files with 1337 additions and 1085 deletions
|
@ -1,16 +1,10 @@
|
|||
#[doc(hidden)]
|
||||
pub struct AppMeta<'b> {
|
||||
// The name displayed to the user when showing version and help/usage information
|
||||
pub name: String,
|
||||
pub bin_name: Option<String>,
|
||||
// A string of author(s) if desired. Displayed when showing help/usage information
|
||||
pub author: Option<&'b str>,
|
||||
// The version displayed to the user
|
||||
pub version: Option<&'b str>,
|
||||
// A brief explanation of the program that gets displayed to the user when shown
|
||||
// help/usage
|
||||
// information
|
||||
pub about: Option<&'b str>,
|
||||
// Additional help information
|
||||
pub more_help: Option<&'b str>,
|
||||
pub usage_str: Option<&'b str>,
|
||||
pub usage: Option<String>,
|
||||
|
|
360
src/app/mod.rs
360
src/app/mod.rs
|
@ -23,30 +23,29 @@ use errors::Error;
|
|||
use errors::Result as ClapResult;
|
||||
|
||||
/// Used to create a representation of a command line program and all possible command line
|
||||
/// arguments.
|
||||
///
|
||||
/// Application settings are set using the "builder pattern" with `.get_matches()` being the
|
||||
/// terminal method that starts the runtime-parsing process and returns information about
|
||||
/// the user supplied arguments (or lack there of).
|
||||
///
|
||||
/// There aren't any mandatory "options" that one must set. The "options" may also appear in any
|
||||
/// order (so long as `.get_matches()` is the last method called).
|
||||
/// arguments. Application settings are set using the "builder pattern" with the
|
||||
/// `.get_matches()` family of methods being the terminal methods that starts the runtime-parsing
|
||||
/// process. These methods then return information about the user supplied arguments (or lack there
|
||||
/// of).
|
||||
///
|
||||
/// **NOTE:** There aren't any mandatory "options" that one must set. The "options" may
|
||||
/// also appear in any order (so long as one of the `App::get_matches*` methods is the last method
|
||||
/// called).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// let matches = App::new("myprog")
|
||||
/// .author("Me, me@mail.com")
|
||||
/// .version("1.0.2")
|
||||
/// .about("Explains in brief what the program does")
|
||||
/// .arg(
|
||||
/// Arg::with_name("in_file").index(1)
|
||||
/// )
|
||||
/// .after_help("Longer explaination to appear after the options when \
|
||||
/// displaying the help information from --help or -h")
|
||||
/// .get_matches();
|
||||
/// let m = App::new("My Program")
|
||||
/// .author("Me, me@mail.com")
|
||||
/// .version("1.0.2")
|
||||
/// .about("Explains in brief what the program does")
|
||||
/// .arg(
|
||||
/// Arg::with_name("in_file").index(1)
|
||||
/// )
|
||||
/// .after_help("Longer explaination to appear after the options when \
|
||||
/// displaying the help information from --help or -h")
|
||||
/// .get_matches();
|
||||
///
|
||||
/// // Your program logic starts here...
|
||||
/// ```
|
||||
|
@ -54,37 +53,49 @@ use errors::Result as ClapResult;
|
|||
pub struct App<'a, 'b>(Parser<'a, 'b>) where 'a: 'b;
|
||||
|
||||
impl<'a, 'b> App<'a, 'b> {
|
||||
/// Creates a new instance of an application requiring a name (such as the binary). The name
|
||||
/// will be displayed to the user when they request to print version or help and usage
|
||||
/// information. The name should not contain spaces (hyphens '-' are ok).
|
||||
///
|
||||
/// Creates a new instance of an application requiring a name. The name may be, but doesn't
|
||||
/// have to be same as the binary. The name will be displayed to the user when they request to
|
||||
/// print version or help and usage information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// let prog = App::new("myprog")
|
||||
/// # .get_matches();
|
||||
/// let prog = App::new("My Program")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn new<S: Into<String>>(n: S) -> Self { App(Parser::with_name(n.into())) }
|
||||
|
||||
/// Creates a new instace of `App` from a .yml (YAML) file. The YAML file must be properly
|
||||
/// formatted or this function will panic!(). A full example of supported YAML objects can be
|
||||
/// found in `examples/17_yaml.rs` and `examples/17_yaml.yml`.
|
||||
/// Creates a new instace of `App` from a .yml (YAML) file. A full example of supported YAML
|
||||
/// objects can be found in `examples/17_yaml.rs` and `examples/17_yaml.yml`. One great use for
|
||||
/// using YAML is when supporting multiple languages and dialects, as each language could be a
|
||||
/// distinct YAML file and determined at compiletime via `cargo` "features" in your
|
||||
/// `Cargo.toml`
|
||||
///
|
||||
/// In order to use this function you must compile with the `features = ["yaml"]` in your
|
||||
/// settings for `[dependencies.clap]` table of your `Cargo.toml`
|
||||
/// In order to use this function you must compile `clap` with the `features = ["yaml"]` in
|
||||
/// your settings for the `[dependencies.clap]` table of your `Cargo.toml`
|
||||
///
|
||||
/// Note, due to how the YAML objects are built there is a convienience macro for loading the
|
||||
/// YAML file (relative to the current file, like modules work). That YAML object can then be
|
||||
/// passed to this function.
|
||||
/// **NOTE:** Due to how the YAML objects are built there is a convienience macro for loading
|
||||
/// the YAML file at compile time (relative to the current file, like modules work). That YAML
|
||||
/// object can then be passed to this function.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The YAML file must be properly formatted or this function will panic!(). A good way to
|
||||
/// ensure this doesn't happen is to run your program with the `--help` switch. If this passes
|
||||
/// without error, you needn't worry because the YAML is properly formatted.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The following example shows how to load a properly formatted YAML file to build an instnace
|
||||
/// of an `App` struct.
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use clap::App;
|
||||
/// let yml = load_yaml!("app.yml");
|
||||
/// let app = App::from_yaml(yml);
|
||||
///
|
||||
/// // continued logic goes here, such as `app.get_matches()` etc.
|
||||
/// ```
|
||||
#[cfg(feature = "yaml")]
|
||||
pub fn from_yaml<'y>(mut yaml: &'y Yaml) -> App<'y, 'y> {
|
||||
|
@ -148,7 +159,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
a = a.subcommand(SubCommand::from_yaml(&sc_yaml));
|
||||
}
|
||||
}
|
||||
if let Some(v) = yaml["arg_groups"].as_vec() {
|
||||
if let Some(v) = yaml["groups"].as_vec() {
|
||||
for ag_yaml in v {
|
||||
a = a.group(ArgGroup::from_yaml(&ag_yaml.as_hash().unwrap()));
|
||||
}
|
||||
|
@ -157,7 +168,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
a
|
||||
}
|
||||
|
||||
/// Sets a string of author(s) and will be displayed to the user when they request the help
|
||||
/// Sets a string of author(s) that will be displayed to the user when they request the help
|
||||
/// information with `--help` or `-h`.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -174,16 +185,19 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
}
|
||||
|
||||
/// Overrides the system-determined binary name. This should only be used when absolutely
|
||||
/// neccessary, such as the binary name for your application is misleading, or perhaps *not*
|
||||
/// how the user should invoke your program.
|
||||
/// neccessary, such as when the binary name for your application is misleading, or perhaps
|
||||
/// *not* how the user should invoke your program.
|
||||
///
|
||||
/// **NOTE:** This command **should not** be used for SubCommands.
|
||||
/// **Pro-tip:** When building things such as third party `cargo` subcommands, this setting
|
||||
/// **should** be used!
|
||||
///
|
||||
/// **NOTE:** This command **should not** be used for `SubCommand`s.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// App::new("My Program")
|
||||
/// .bin_name("my_binary")
|
||||
/// # ;
|
||||
/// ```
|
||||
|
@ -192,8 +206,8 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets a string briefly describing what the program does and will be displayed when
|
||||
/// displaying help information.
|
||||
/// Sets a string describing what the program does. This will be displayed when displaying help
|
||||
/// information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -208,17 +222,16 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds additional help information to be displayed in addition to and directly after
|
||||
/// auto-generated help. This information is displayed **after** the auto-generated help
|
||||
/// information. This additional help is often used to describe how to use the arguments,
|
||||
/// or caveats to be noted.
|
||||
/// Adds additional help information to be displayed in addition to auto-generated help. This
|
||||
/// information is displayed **after** the auto-generated help information. This is often used
|
||||
/// to describe how to use the arguments, or caveats to be noted.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::App;
|
||||
/// App::new("myprog")
|
||||
/// .after_help("Does really amazing things to great people")
|
||||
/// .after_help("Does really amazing things to great people...but be careful with -R")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn after_help<S: Into<&'b str>>(mut self, help: S) -> Self {
|
||||
|
@ -229,6 +242,10 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// Sets a string of the version number to be displayed when displaying version or help
|
||||
/// information.
|
||||
///
|
||||
/// **Pro-tip:** Use `clap`s convienience macro `crate_version!` to automatically set your
|
||||
/// application's version to the same thing as your crate at compile time. See the `examples/`
|
||||
/// directory for more information
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -245,7 +262,10 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// Sets a custom usage string to override the auto-generated usage string.
|
||||
///
|
||||
/// This will be displayed to the user when errors are found in argument parsing, or when you
|
||||
/// call `ArgMatcher::usage()`
|
||||
/// call `ArgMatches::usage`
|
||||
///
|
||||
/// **CAUTION:** Using this setting disables `clap`s "context-aware" usage strings. After this
|
||||
/// setting is set, this will be the only usage string displayed to the user!
|
||||
///
|
||||
/// **NOTE:** You do not need to specify the "USAGE: \n\t" portion, as that will
|
||||
/// still be applied by `clap`, you only need to specify the portion starting
|
||||
|
@ -254,7 +274,6 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// **NOTE:** This will not replace the entire help message, *only* the portion
|
||||
/// showing the usage.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -271,7 +290,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// Sets a custom help message and overrides the auto-generated one. This should only be used
|
||||
/// when the auto-generated message does not suffice.
|
||||
///
|
||||
/// This will be displayed to the user when they use the default `--help` or `-h`
|
||||
/// This will be displayed to the user when they use `--help` or `-h`
|
||||
///
|
||||
/// **NOTE:** This replaces the **entire** help message, so nothing will be auto-generated.
|
||||
///
|
||||
|
@ -279,7 +298,6 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// are using subcommands, those help messages will still be auto-generated unless you
|
||||
/// specify a `.help()` for them as well.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -309,20 +327,21 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
|
||||
/// Sets the short version of the `help` argument without the preceding `-`.
|
||||
///
|
||||
/// By default `clap` automatically assigns `h`, but this can be overridden
|
||||
/// By default `clap` automatically assigns `h`, but this can be overridden by defining your
|
||||
/// own argument with a lowercase `h` as the `short`. `clap` lazily generates these help
|
||||
/// arguments **after** you've defined any arguments of your own.
|
||||
///
|
||||
/// **NOTE:** Any leading `-` characters will be stripped, and only the first
|
||||
/// non `-` chacter will be used as the `short` version
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// // Using an uppercase `H` instead of the default lowercase `h`
|
||||
/// .help_short("H")
|
||||
/// .help_short("H") // Using an uppercase `H` instead of the default lowercase `h`
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn help_short<S: AsRef<str> + 'b>(mut self, s: S) -> Self {
|
||||
self.0.help_short(s.as_ref());
|
||||
self
|
||||
|
@ -330,26 +349,29 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
|
||||
/// Sets the short version of the `version` argument without the preceding `-`.
|
||||
///
|
||||
/// By default `clap` automatically assigns `V`, but this can be overridden
|
||||
/// By default `clap` automatically assigns `V`, but this can be overridden by defining your
|
||||
/// own argument with a uppercase `V` as the `short`. `clap` lazily generates these version
|
||||
/// arguments **after** you've defined any arguments of your own.
|
||||
///
|
||||
/// **NOTE:** Any leading `-` characters will be stripped, and only the first
|
||||
/// non `-` chacter will be used as the `short` version
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// // Using a lowercase `v` instead of the default capital `V`
|
||||
/// .version_short("v")
|
||||
/// .version_short("v") // Using a lowercase `v` instead of the default capital `V`
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn version_short<S: AsRef<str>>(mut self, s: S) -> Self {
|
||||
self.0.version_short(s.as_ref());
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables Application level settings, passed as argument
|
||||
/// Enables a single Application level settings.
|
||||
///
|
||||
/// See `AppSettings` for a full list of possibilities and examples.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -365,14 +387,16 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Enables multiple Application level settings, passed as argument
|
||||
/// Enables multiple Application level settings
|
||||
///
|
||||
/// See `AppSettings` for a full list of possibilities and examples.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// .settings( &[AppSettings::SubcommandRequired,
|
||||
/// .settings(&[AppSettings::SubcommandRequired,
|
||||
/// AppSettings::WaitOnError])
|
||||
/// # ;
|
||||
/// ```
|
||||
|
@ -383,14 +407,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds an argument to the list of valid possibilties manually. This method allows you full
|
||||
/// control over the arguments settings and options (as well as dynamic generation). It also
|
||||
/// allows you specify several more advanced configuration options such as relational rules
|
||||
/// (exclusions and requirements).
|
||||
///
|
||||
/// The only disadvantage to this method is that it's more verbose, and arguments must be added
|
||||
/// one at a time. Using `Arg::from_usage` helps with the verbosity, and still allows full
|
||||
/// control over the advanced configuration options.
|
||||
/// Adds an argument to the list of valid possibilties.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -415,8 +432,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds multiple arguments to the list of valid possibilties by iterating over a Vec of Args
|
||||
///
|
||||
/// Adds multiple arguments to the list of valid possibilties
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -424,7 +440,7 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// .args(
|
||||
/// &[Arg::from_usage("[debug] -d 'turns on debugging info"),
|
||||
/// &[Arg::from_usage("[debug] -d 'turns on debugging info'"),
|
||||
/// Arg::with_name("input").index(1).help("the input file to use")]
|
||||
/// )
|
||||
/// # ;
|
||||
|
@ -436,20 +452,18 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// A convienience method for adding a single basic argument (one without advanced
|
||||
/// relational rules) from a usage type string. The string used follows the same rules and
|
||||
/// syntax as `Arg::from_usage()`
|
||||
///
|
||||
/// The downside to using this method is that you can not set any additional properties of the
|
||||
/// `Arg` other than what `Arg::from_usage()` supports.
|
||||
/// A convienience method for adding a single argument from a usage type string. The string
|
||||
/// used follows the same rules and syntax as `Arg::from_usage()`
|
||||
///
|
||||
/// **NOTE:** The downside to using this method is that you can not set any additional
|
||||
/// properties of the `Arg` other than what `Arg::from_usage()` supports.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// .arg_from_usage("-c --conf=<config> 'Sets a configuration file to use'")
|
||||
/// .arg_from_usage("-c --config=<FILE> 'Sets a configuration file to use'")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn arg_from_usage(mut self, usage: &'a str) -> Self {
|
||||
|
@ -460,11 +474,8 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// Adds multiple arguments at once from a usage string, one per line. See `Arg::from_usage()`
|
||||
/// for details on the syntax and rules supported.
|
||||
///
|
||||
/// Like `App::arg_from_usage()` the downside is you only set properties for the `Arg`s which
|
||||
/// `Arg::from_usage()` supports. But here the benefit is pretty strong, as the readability is
|
||||
/// greatly enhanced, especially if you don't need any of the more advanced configuration
|
||||
/// options.
|
||||
///
|
||||
/// **NOTE:** Like `App::arg_from_usage()` the downside is you only set properties for the
|
||||
/// `Arg`s which `Arg::from_usage()` supports.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -472,9 +483,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// # use clap::{App, Arg};
|
||||
/// App::new("myprog")
|
||||
/// .args_from_usage(
|
||||
/// "-c --conf=[config] 'Sets a configuration file to use'
|
||||
/// "-c --config=[FILE] 'Sets a configuration file to use'
|
||||
/// [debug]... -d 'Sets the debugging level'
|
||||
/// <input> 'The input file to use'"
|
||||
/// <FILE> 'The input file to use'"
|
||||
/// )
|
||||
/// # ;
|
||||
/// ```
|
||||
|
@ -485,75 +496,66 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds an ArgGroup to the application. ArgGroups are a family of related arguments. By
|
||||
/// placing them in a logical group, you make easier requirement and exclusion rules. For
|
||||
/// instance, you can make an 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).
|
||||
/// Adds an `ArgGroup` to the application. `ArgGroup`s are a family of related arguments. By
|
||||
/// placing them in a logical group, you can build easier requirement and exclusion rules. For
|
||||
/// instance, you can make an entire `ArgGroup` required, meaning that one (and *only* one) argument
|
||||
/// from that group must be present at runtime.
|
||||
///
|
||||
/// You can also do things such as name an ArgGroup as a confliction, meaning any of the
|
||||
/// arguments that belong to that group will cause a failure if present.
|
||||
/// You can also do things such as name an `ArgGroup` as a conflict to another argument.
|
||||
/// Meaning any of the arguments that belong to that group will cause a failure if present with
|
||||
/// the conflicting argument.
|
||||
///
|
||||
/// Perhaps the most common use of ArgGroups is to require one and *only* one argument to be
|
||||
/// present out of a given set. For example, lets say that you were building an application
|
||||
/// where one could set a given version number by supplying a string using an option argument,
|
||||
/// such as `--set-ver v1.2.3`, you also wanted to support automatically using a previous
|
||||
/// version numer 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 perhaps you want to specify that *at least one* of them is used. You can create a
|
||||
/// group
|
||||
/// Another added benfit of `ArgGroup`s is that you can extract a value from a group instead of
|
||||
/// determining exactly which argument was used.
|
||||
///
|
||||
/// Finally, using `ArgGroup`s to ensure exclusion between arguments is another very common use
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The following example demonstrates using an `ArgGroup` to ensure that one, and only one, of
|
||||
/// the arguments from the specified group is present at runtime.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # App::new("app")
|
||||
/// .args_from_usage("--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch")
|
||||
/// .group(ArgGroup::with_name("vers")
|
||||
/// .args(&["ver", "major", "minor","patch"])
|
||||
/// .required(true))
|
||||
/// App::new("app")
|
||||
/// .args_from_usage(
|
||||
/// "--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch'")
|
||||
/// .group(ArgGroup::with_name("vers")
|
||||
/// .args(&["set-ver", "major", "minor","patch"])
|
||||
/// .required(true))
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn group(mut self, group: ArgGroup<'a>) -> Self {
|
||||
self.0.add_group(group);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a ArgGroups to the application. ArgGroups are a family of related arguments. By
|
||||
/// placing them in a logical group, you make easier requirement and exclusion rules. For
|
||||
/// instance, you can make an 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, meaning any of the
|
||||
/// arguments that belong to that group will cause a failure if present.
|
||||
///
|
||||
/// Perhaps the most common use of ArgGroups is to require one and *only* one argument to be
|
||||
/// present out of a given set. For example, lets say that you were building an application
|
||||
/// where one could set a given version number by supplying a string using an option argument,
|
||||
/// such as `--set-ver v1.2.3`, you also wanted to support automatically using a previous
|
||||
/// version numer 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 perhaps you want to specify that *at least one* of them is used. You can create a
|
||||
/// group
|
||||
///
|
||||
/// Adds multiple `ArgGroup`s to the application at once.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # App::new("app")
|
||||
/// .args_from_usage("--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch")
|
||||
/// .group(ArgGroup::with_name("vers")
|
||||
/// .args(&["ver", "major", "minor","patch"])
|
||||
/// .required(true))
|
||||
/// App::new("app")
|
||||
/// .args_from_usage(
|
||||
/// "--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch'
|
||||
/// -c [FILE] 'a config file'
|
||||
/// -i [IFACE] 'an interface'")
|
||||
/// .groups(&[
|
||||
/// ArgGroup::with_name("vers")
|
||||
/// .args(&["set-ver", "major", "minor","patch"])
|
||||
/// .required(true),
|
||||
/// ArgGroup::with_name("input")
|
||||
/// .args(&["c", "i"])
|
||||
/// ])
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn groups(mut self, groups: &[ArgGroup<'a>]) -> Self {
|
||||
for g in groups {
|
||||
self = self.group(g.into());
|
||||
|
@ -561,21 +563,19 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Adds a subcommand to the list of valid possibilties. Subcommands are effectively sub apps,
|
||||
/// Adds a subcommand to the list of valid possibilties. Subcommands are effectively sub-apps,
|
||||
/// because they can contain their own arguments, subcommands, version, usage, etc. They also
|
||||
/// function just like apps, in that they get their own auto generated help, version, and
|
||||
/// usage.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("config")
|
||||
/// .about("Controls configuration features")
|
||||
/// .arg_from_usage("<config> 'Required configuration file to use'"))
|
||||
/// // Additional subcommand configuration goes here, such as other arguments...
|
||||
/// App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("config")
|
||||
/// .about("Controls configuration features")
|
||||
/// .arg_from_usage("<config> 'Required configuration file to use'"))
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn subcommand(mut self, subcmd: App<'a, 'b>) -> Self {
|
||||
|
@ -597,7 +597,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// SubCommand::with_name("debug").about("Controls debug functionality")])
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn subcommands(mut self, subcmds: Vec<App<'a, 'b>>) -> Self {
|
||||
pub fn subcommands<I>(mut self, subcmds: I) -> Self
|
||||
where I: IntoIterator<Item = App<'a, 'b>>
|
||||
{
|
||||
for subcmd in subcmds.into_iter() {
|
||||
self.0.add_subcommand(subcmd);
|
||||
}
|
||||
|
@ -608,9 +610,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// Prints the full help message to `io::stdout()` using a `BufWriter`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::App;
|
||||
/// # use std::io;
|
||||
/// let app = App::new("myprog");
|
||||
/// app.print_help();
|
||||
/// ```
|
||||
|
@ -622,9 +624,11 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
|
||||
/// Writes the full help message to the user to a `io::Write` object
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::App;
|
||||
/// # use std::io;
|
||||
/// use std::io;
|
||||
/// let mut app = App::new("myprog");
|
||||
/// let mut out = io::stdout();
|
||||
/// app.write_help(&mut out).ok().expect("failed to write to stdout");
|
||||
|
@ -633,13 +637,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
self.0.write_help(w)
|
||||
}
|
||||
|
||||
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
|
||||
/// the real parsing function for all subcommands
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If any arguments contain invalid unicode characters. If this is not desired it is
|
||||
/// recommended to use the `*_safe()` or `*_lossy()` versions of this method.
|
||||
/// Starts the parsing process, upon a failed parse an error will be displayed to the user and
|
||||
/// the process with exit with the appropriate error code. By default this method gets matches
|
||||
/// from `env::args_os`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -650,21 +650,17 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// .get_matches();
|
||||
/// ```
|
||||
pub fn get_matches(self) -> ArgMatches<'a> {
|
||||
// Start the parsing
|
||||
self.get_matches_from(&mut env::args_os())
|
||||
}
|
||||
|
||||
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
|
||||
/// the real parsing function for all subcommands
|
||||
/// Starts the parsing process. This method will return a `Result` type instead of exiting the
|
||||
/// the process on failed parse. By default this method gets matches
|
||||
/// from `env::args_os`
|
||||
///
|
||||
/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
|
||||
/// used. It will return an error, where the `kind` is a `ErrorKind::HelpDisplayed`
|
||||
/// or `ErrorKind::VersionDisplayed` respectively. You must call `error.exit()` or
|
||||
/// perform a `std::process::exit` yourself.
|
||||
///
|
||||
/// **NOTE:** This method should only be used when is absolutely necessary to handle errors
|
||||
/// manually.
|
||||
///
|
||||
/// perform a `std::process::exit`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -673,22 +669,19 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// let matches = App::new("myprog")
|
||||
/// // Args and options go here...
|
||||
/// .get_matches_safe()
|
||||
/// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) });
|
||||
/// .unwrap_or_else( |e| e.exit() );
|
||||
/// ```
|
||||
pub fn get_matches_safe(self) -> ClapResult<ArgMatches<'a>> {
|
||||
// Start the parsing
|
||||
self.get_matches_from_safe(&mut env::args_os())
|
||||
}
|
||||
|
||||
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
|
||||
/// the real parsing function for all subcommands
|
||||
///
|
||||
/// **NOTE:** The first argument will be parsed as the binary name.
|
||||
///
|
||||
/// **NOTE:** This method should only be used when absolutely necessary, such as needing to
|
||||
/// parse arguments from something other than `std::env::args()`. If you are unsure, use
|
||||
/// `App::get_matches()`
|
||||
/// Starts the parsing process. Like `App::get_matches` this method does not return a `Result`
|
||||
/// and will automatically exit with an error message. This method, however, lets you specify
|
||||
/// what iterator to use when performing matches, such as a `Vec` of your making.
|
||||
///
|
||||
/// **NOTE:** The first argument will be parsed as the binary name unless
|
||||
/// `AppSettings::NoBinaryName` is used
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -710,26 +703,16 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
|
||||
/// the real parsing function for all subcommands
|
||||
/// Starts the parsing process. A combination of `App::get_matches_from`, and
|
||||
/// `App::get_matches_safe`
|
||||
///
|
||||
/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
|
||||
/// used. It will return an error, where the `kind` is a `ErrorKind::HelpDisplayed`
|
||||
/// or `ErrorKind::VersionDisplayed` respectively. You must call `error.exit()` or
|
||||
/// perform a `std::process::exit` yourself.
|
||||
///
|
||||
/// **NOTE:** The first argument will be parsed as the binary name.
|
||||
///
|
||||
/// **NOTE:** This method should only be used when absolutely necessary, such as needing to
|
||||
/// parse arguments from something other than `std::env::args()`. If you are unsure, use
|
||||
/// `App::get_matches_safe()`
|
||||
///
|
||||
/// **NOTE:** This method should only be used when is absolutely necessary to handle errors
|
||||
/// manually.
|
||||
///
|
||||
/// **NOTE:** Invalid unicode characters will result in an `Err` with type
|
||||
/// `ErrorKind::InvalidUtf8`
|
||||
///
|
||||
/// **NOTE:** The first argument will be parsed as the binary name unless
|
||||
/// `AppSettings::NoBinaryName` is used
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -753,17 +736,8 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// the desired functionality, instead prefer `App::get_matches_from_safe` which *does*
|
||||
/// consume `self`.
|
||||
///
|
||||
/// **NOTE:** The first argument will be parsed as the binary name.
|
||||
///
|
||||
/// **NOTE:** This method should only be used when absolutely necessary, such as needing to
|
||||
/// parse arguments from something other than `std::env::args()`. If you are unsure, use
|
||||
/// `App::get_matches_safe()`
|
||||
///
|
||||
/// **NOTE:** This method should only be used when is absolutely necessary to handle errors
|
||||
/// manually.
|
||||
///
|
||||
/// **NOTE:** Invalid unicode characters will result in an `Err` with type
|
||||
/// `ErrorKind::InvalidUtf8`
|
||||
/// **NOTE:** The first argument will be parsed as the binary name unless
|
||||
/// `AppSettings::NoBinaryName` is used
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -15,7 +15,7 @@ use args::{AnyArg, ArgMatcher};
|
|||
use args::settings::{ArgSettings, ArgFlags};
|
||||
use errors::{ErrorKind, Error};
|
||||
use errors::Result as ClapResult;
|
||||
use utf8::INVALID_UTF8;
|
||||
use INVALID_UTF8;
|
||||
use suggestions;
|
||||
use INTERNAL_ERROR_MSG;
|
||||
use SubCommand;
|
||||
|
@ -24,6 +24,7 @@ use osstringext::OsStrExt2;
|
|||
use app::meta::AppMeta;
|
||||
use args::MatchedArg;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct Parser<'a, 'b> where 'a: 'b {
|
||||
required: Vec<&'b str>,
|
||||
short_list: Vec<char>,
|
||||
|
@ -114,30 +115,23 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
|
||||
// actually adds the arguments
|
||||
pub fn add_arg(&mut self, a: &Arg<'a, 'b>) {
|
||||
if self.flags.iter().any(|f| &f.name == &a.name) ||
|
||||
self.opts.iter().any(|o| o.name == a.name) ||
|
||||
self.positionals.values().any(|p| p.name == a.name) {
|
||||
panic!("Non-unique argument name: {} is already in use", a.name);
|
||||
}
|
||||
assert!(!(self.flags.iter().any(|f| &f.name == &a.name)
|
||||
|| self.opts.iter().any(|o| o.name == a.name)
|
||||
|| self.positionals.values().any(|p| p.name == a.name)),
|
||||
format!("Non-unique argument name: {} is already in use", a.name));
|
||||
if let Some(grp) = a.group {
|
||||
let ag = self.groups.entry(grp).or_insert_with(|| ArgGroup::with_name(grp));
|
||||
ag.args.push(a.name);
|
||||
}
|
||||
if let Some(s) = a.short {
|
||||
if self.short_list.contains(&s) {
|
||||
panic!("Argument short must be unique\n\n\t-{} is already in use",
|
||||
s);
|
||||
} else {
|
||||
self.short_list.push(s);
|
||||
}
|
||||
assert!(!self.short_list.contains(&s),
|
||||
format!("Argument short must be unique\n\n\t-{} is already in use", s));
|
||||
self.short_list.push(s);
|
||||
}
|
||||
if let Some(l) = a.long {
|
||||
if self.long_list.contains(&l) {
|
||||
panic!("Argument long must be unique\n\n\t--{} is already in use",
|
||||
l);
|
||||
} else {
|
||||
self.long_list.push(l);
|
||||
}
|
||||
assert!(!self.long_list.contains(&l),
|
||||
format!("Argument long must be unique\n\n\t--{} is already in use", l));
|
||||
self.long_list.push(l);
|
||||
if l == "help" {
|
||||
self.set(AppSettings::NeedsLongHelp);
|
||||
} else if l == "version" {
|
||||
|
@ -153,12 +147,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
} else {
|
||||
a.index.unwrap() as usize
|
||||
};
|
||||
if self.positionals.contains_key(&i) {
|
||||
panic!("Argument \"{}\" has the same index as another positional \
|
||||
assert!(!self.positionals.contains_key(&i),
|
||||
format!("Argument \"{}\" has the same index as another positional \
|
||||
argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
|
||||
to take multiple values",
|
||||
a.name);
|
||||
}
|
||||
to take multiple values", a.name));
|
||||
let pb = PosBuilder::from_arg(&a, i as u8, &mut self.required);
|
||||
self.positionals.insert(i, pb);
|
||||
} else if a.is_set(ArgSettings::TakesValue) {
|
||||
|
@ -169,11 +161,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
self.flags.push(fb);
|
||||
}
|
||||
if a.is_set(ArgSettings::Global) {
|
||||
if a.is_set(ArgSettings::Required) {
|
||||
panic!("Global arguments cannot be required.\n\n\t'{}' is marked as global and \
|
||||
required",
|
||||
a.name);
|
||||
}
|
||||
assert!(!a.is_set(ArgSettings::Required),
|
||||
format!("Global arguments cannot be required.\n\n\t'{}' is marked as global and \
|
||||
required", a.name));
|
||||
self.global_args.push(a.into());
|
||||
}
|
||||
}
|
||||
|
@ -383,7 +373,6 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
self.settings.set(s)
|
||||
}
|
||||
|
||||
|
||||
pub fn verify_positionals(&mut self) {
|
||||
// Because you must wait until all arguments have been supplied, this is the first chance
|
||||
// to make assertions on positional argument indexes
|
||||
|
@ -392,13 +381,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
// positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
|
||||
// but no 2)
|
||||
if let Some((idx, ref p)) = self.positionals.iter().rev().next() {
|
||||
if idx != self.positionals.len() {
|
||||
panic!("Found positional argument \"{}\" who's index is {} but there are only {} \
|
||||
positional arguments defined",
|
||||
p.name,
|
||||
idx,
|
||||
self.positionals.len());
|
||||
}
|
||||
assert!(!(idx != self.positionals.len()),
|
||||
format!("Found positional argument \"{}\" who's index is {} but there are only {} \
|
||||
positional arguments defined", p.name, idx, self.positionals.len()));
|
||||
}
|
||||
|
||||
// Next we verify that only the highest index has a .multiple(true) (if any)
|
||||
|
|
|
@ -25,6 +25,7 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct AppFlags(Flags);
|
||||
|
||||
|
@ -59,18 +60,45 @@ impl AppFlags {
|
|||
/// Application level settings, which affect how `App` operates
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub enum AppSettings {
|
||||
/// Allows subcommands to override all requirements of the parent (this command). For example
|
||||
/// if you had a subcommand or even top level application which had a required arguments that
|
||||
/// are only required as long as there is no subcommand present.
|
||||
/// Allows subcommands to override all requirements of the parent command. For example
|
||||
/// if you had a subcommand or top level application which had a required argument that
|
||||
/// are only required as long as there is no subcommand present, using this setting would allow
|
||||
/// you set those arguments to `required(true)` and yet receive no error so long as the user
|
||||
/// uses a valid subcommand instead.
|
||||
///
|
||||
/// **NOTE:** This defaults to false (using subcommand does *not* negate requirements)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// This first example shows that it is an error to not use a required argument
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings, SubCommand, ErrorKind};
|
||||
/// let err = App::new("myprog")
|
||||
/// .setting(AppSettings::SubcommandsNegateReqs)
|
||||
/// .arg(Arg::with_name("opt").required(true))
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches_from_safe(vec![
|
||||
/// "myprog"
|
||||
/// ]);
|
||||
/// assert!(err.is_err());
|
||||
/// assert_eq!(err.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// This next example shows that it is no longer error to not use a required argument if a
|
||||
/// valid subcommand is used.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings, SubCommand, ErrorKind};
|
||||
/// let noerr = App::new("myprog")
|
||||
/// .setting(AppSettings::SubcommandsNegateReqs)
|
||||
/// .arg(Arg::with_name("opt").required(true))
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches_from_safe(vec![
|
||||
/// "myprog", "test"
|
||||
/// ]);
|
||||
/// assert!(noerr.is_ok());
|
||||
/// # ;
|
||||
/// ```
|
||||
SubcommandsNegateReqs,
|
||||
|
@ -80,10 +108,16 @@ pub enum AppSettings {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// ```rust
|
||||
/// # use clap::{App, AppSettings, SubCommand, ErrorKind};
|
||||
/// let err = App::new("myprog")
|
||||
/// .setting(AppSettings::SubcommandRequired)
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches_from_safe(vec![
|
||||
/// "myprog",
|
||||
/// ]);
|
||||
/// assert!(err.is_err());
|
||||
/// assert_eq!(err.unwrap_err().kind, ErrorKind::MissingSubcommand);
|
||||
/// # ;
|
||||
/// ```
|
||||
SubcommandRequired,
|
||||
|
@ -94,18 +128,18 @@ pub enum AppSettings {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// .setting(AppSettings::ArgRequiredElseHelp)
|
||||
/// # ;
|
||||
/// ```
|
||||
ArgRequiredElseHelp,
|
||||
/// Uses version of the current command for all subcommands. (Defaults to false; subcommands
|
||||
/// have independant version strings)
|
||||
/// Specifies to version of the current command for all child subcommands. (Defaults to false;
|
||||
/// subcommands have independant version strings from their parents)
|
||||
///
|
||||
/// **NOTE:** The version for the current command and this setting must be set **prior** to
|
||||
/// adding any subcommands
|
||||
/// **NOTE:** The version for the current command **and** this setting must be set **prior** to
|
||||
/// adding any child subcommands
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -116,7 +150,7 @@ pub enum AppSettings {
|
|||
/// .setting(AppSettings::GlobalVersion)
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches();
|
||||
/// // running `myprog test --version` will display
|
||||
/// // running `$ myprog test --version` will display
|
||||
/// // "myprog-test v1.1"
|
||||
/// ```
|
||||
GlobalVersion,
|
||||
|
@ -125,23 +159,24 @@ pub enum AppSettings {
|
|||
///
|
||||
/// **NOTE:** This setting must be set **prior** adding any subcommands
|
||||
///
|
||||
/// **NOTE:** Do not set this value to false, it will have undesired results!
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// ```rust
|
||||
/// # use clap::{App, SubCommand, AppSettings, ErrorKind};
|
||||
/// let res = App::new("myprog")
|
||||
/// .version("v1.1")
|
||||
/// .setting(AppSettings::VersionlessSubcommands)
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches();
|
||||
/// // running `myprog test --version` will display unknown argument error
|
||||
/// .get_matches_from_safe(vec![
|
||||
/// "myprog", "test", "-V"
|
||||
/// ]);
|
||||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
|
||||
/// ```
|
||||
VersionlessSubcommands,
|
||||
/// By default the auto-generated help message groups flags, options, and positional arguments
|
||||
/// separately. This setting disable that and groups flags and options together presenting a
|
||||
/// more unified help message (a la getopts or docopt style).
|
||||
/// Groups flags and options together presenting a more unified help message (a la `getopts` or
|
||||
/// `docopt` style). The default is the auto-generated help message groups flags, options
|
||||
/// separately.
|
||||
///
|
||||
/// **NOTE:** This setting is cosmetic only and does not affect any functionality.
|
||||
///
|
||||
|
@ -160,8 +195,7 @@ pub enum AppSettings {
|
|||
///
|
||||
/// This is most useful when writing an application which is run from a GUI shortcut, or on
|
||||
/// Windows where a user tries to open the binary by double-clicking instead of using the
|
||||
/// command line (i.e. set `.arg_required_else_help(true)` and `.wait_on_error(true)` to
|
||||
/// display the help in such a case).
|
||||
/// command line.
|
||||
///
|
||||
/// **NOTE:** This setting is **not** recursive with subcommands, meaning if you wish this
|
||||
/// behavior for all subcommands, you must set this on each command (needing this is extremely
|
||||
|
@ -169,7 +203,7 @@ pub enum AppSettings {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// .setting(AppSettings::WaitOnError)
|
||||
|
@ -180,15 +214,15 @@ pub enum AppSettings {
|
|||
/// subcommands are present at runtime (i.e. an empty run such as, `$ myprog`.
|
||||
///
|
||||
/// **NOTE:** This should *not* be used with `.subcommand_required()` as they do the same
|
||||
/// thing, except one prints the help text, and one prints an error.
|
||||
/// thing, except this prints the help text, and the other prints an error.
|
||||
///
|
||||
/// **NOTE:** If the user specifies arguments at runtime, but no subcommand the help text will
|
||||
/// still be displayed and exit. If this is *not* the desired result, consider using
|
||||
/// `.arg_required_else_help()`
|
||||
/// `ArgRequiredElseHelp` instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings};
|
||||
/// App::new("myprog")
|
||||
/// .setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
|
@ -199,7 +233,7 @@ pub enum AppSettings {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings, SubCommand};
|
||||
/// App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("test")
|
||||
|
@ -207,43 +241,42 @@ pub enum AppSettings {
|
|||
/// # ;
|
||||
/// ```
|
||||
Hidden,
|
||||
/// Specifies that the final positional argument is a vararg and that `clap` should not attempt
|
||||
/// to parse any further args.
|
||||
/// Specifies that the final positional argument is a "VarArg" and that `clap` should not
|
||||
/// attempt to parse any further args.
|
||||
///
|
||||
/// The values of the trailing positional argument will contain all args from itself on.
|
||||
///
|
||||
/// **NOTE:** The final positional argument **must** have `.multiple(true)` or usage token
|
||||
/// **NOTE:** The final positional argument **must** have `.multiple(true)` or the usage string
|
||||
/// equivalent.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings};
|
||||
/// let m = App::new("myprog")
|
||||
/// .setting(AppSettings::TrailingVarArg)
|
||||
/// .arg(Arg::from_usage("<cmd>... 'commands to run'"))
|
||||
/// .get_matches_from(vec!["myprog", "some_command", "-r", "set"]);
|
||||
/// .get_matches_from(vec!["myprog", "arg1", "-r", "val1"]);
|
||||
///
|
||||
/// assert_eq!(m.values_of("cmd").unwrap().collect::<Vec<_>>(), &["some_command", "-r", "set"]);
|
||||
/// let trail: Vec<&str> = m.values_of("cmd").unwrap().collect();
|
||||
/// assert_eq!(trail, ["arg1", "-r", "val1"]);
|
||||
/// ```
|
||||
TrailingVarArg,
|
||||
/// Specifies that the parser should not assume the first argument passed is the binary name.
|
||||
/// This is normally the case when using a "daemon" style mode, or an interactive CLI where one
|
||||
/// one would not normally type the binary or program name for each command.
|
||||
///
|
||||
/// **NOTE:** This should only be used when you absolutely know it's what you need. 99% of the
|
||||
/// cases out there don't need this setting.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings};
|
||||
/// let m = App::new("myprog")
|
||||
/// .setting(AppSettings::NoBinaryName)
|
||||
/// .arg(Arg::from_usage("<cmd>... 'commands to run'"))
|
||||
/// .get_matches_from(vec!["some_command", "-r", "set"]);
|
||||
/// .get_matches_from(vec!["command", "set"]);
|
||||
///
|
||||
/// assert_eq!(m.values_of("cmd").unwrap().collect::<Vec<_>>(), &["some_command", "-r", "set"]);
|
||||
/// let cmds: Vec<&str> = m.values_of("cmd").unwrap().collect();
|
||||
/// assert_eq!(cmds, ["command", "set"]);
|
||||
/// ```
|
||||
NoBinaryName,
|
||||
/// Specifies that an unexpected argument positional arguments which would otherwise cause a
|
||||
|
@ -256,30 +289,35 @@ pub enum AppSettings {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, AppSettings};
|
||||
/// // Assume there is a third party subcommand named myprog-subcmd
|
||||
/// // Assume there is an external subcommand named "subcmd"
|
||||
/// let m = App::new("myprog")
|
||||
/// .setting(AppSettings::AllowExternalSubcommands)
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
|
||||
/// ]);
|
||||
/// // All trailing arguments will be stored under the subcommands sub-matches under a value
|
||||
/// // of their runtime name (in this case "subcmd")
|
||||
///
|
||||
/// // All trailing arguments will be stored under the subcommand's sub-matches using a value
|
||||
/// // of the runtime subcommand name (in this case "subcmd")
|
||||
/// match m.subcommand() {
|
||||
/// (external, Some(ext_m)) => {
|
||||
/// let ext_args: Vec<&str> = ext_m.values_of(external).unwrap().collect();
|
||||
/// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
|
||||
/// },
|
||||
/// _ => unreachable!()
|
||||
/// _ => {},
|
||||
/// }
|
||||
/// ```
|
||||
AllowExternalSubcommands,
|
||||
/// Specifies that any invalid UTF-8 code points should be treated as an error and fail
|
||||
/// with a `ErrorKind::InvalidUtf8` error.
|
||||
///
|
||||
/// **NOTE:** This rule only applies to argument values, as flags, options, and subcommands
|
||||
/// only allow valid UTF-8 code points.
|
||||
/// **NOTE:** This rule only applies to argument values, as flags, options, and subcommands
|
||||
/// themselves only allow valid UTF-8 code points.
|
||||
///
|
||||
/// # Platform Specific
|
||||
///
|
||||
/// Non Windows systems only
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -305,10 +343,14 @@ pub enum AppSettings {
|
|||
///
|
||||
/// **NOTE:** Using argument values with invalid UTF-8 code points requires using Either
|
||||
/// `ArgMatches::os_value(s)_of` or `ArgMatches::lossy_value(s)_of` for those particular
|
||||
/// arguments which may have have invalid UTF-8 values
|
||||
/// arguments which may contain invalid UTF-8 values
|
||||
///
|
||||
/// **NOTE:** This rule only applies to argument values, as flags, options, and subcommands
|
||||
/// only allow valid UTF-8 code points.
|
||||
/// themselves only allow valid UTF-8 code points.
|
||||
///
|
||||
/// # Platform Specific
|
||||
///
|
||||
/// Non Windows systems only
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -330,13 +372,17 @@ pub enum AppSettings {
|
|||
/// assert_eq!(m.os_value_of("arg").unwrap().as_bytes(), &[0xe9]);
|
||||
/// ```
|
||||
AllowInvalidUtf8,
|
||||
/// Specifies whether or not leading hyphens are allowed in argument values, such as `-10`
|
||||
/// Specifies that leading hyphens are allowed in argument values, such as `-10`
|
||||
///
|
||||
/// **NOTE:** This can only be set application wide
|
||||
/// **NOTE:** This can only be set application wide and not on a per argument basis.
|
||||
///
|
||||
/// **NOTE:** Use this setting with caution as it silences certain circumstances which would
|
||||
/// otherwise be an error (such as accidentally forgetting to specify a value for leading
|
||||
/// option)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{Arg, App, AppSettings};
|
||||
/// // Imagine you needed to represent negative numbers as well, such as -10
|
||||
/// let m = App::new("nums")
|
||||
|
@ -348,6 +394,7 @@ pub enum AppSettings {
|
|||
///
|
||||
/// assert_eq!(m.value_of("neg"), Some("-20"));
|
||||
/// # ;
|
||||
/// ```
|
||||
AllowLeadingHyphen,
|
||||
#[doc(hidden)]
|
||||
NeedsLongVersion,
|
||||
|
@ -372,10 +419,9 @@ impl FromStr for AppSettings {
|
|||
"waitonerror" => Ok(AppSettings::WaitOnError),
|
||||
"subcommandrequiredelsehelp" => Ok(AppSettings::SubcommandRequiredElseHelp),
|
||||
"hidden" => Ok(AppSettings::Hidden),
|
||||
"AllowExternalSubcommands" => Ok(AppSettings::AllowExternalSubcommands),
|
||||
"allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands),
|
||||
"trailingvararg" => Ok(AppSettings::TrailingVarArg),
|
||||
"nobinaryname" => Ok(AppSettings::NoBinaryName),
|
||||
"allowexternalsubcommands" => Ok(AppSettings::AllowExternalSubcommands),
|
||||
"strictutf8" => Ok(AppSettings::StrictUtf8),
|
||||
"allowinvalidutf8" => Ok(AppSettings::AllowInvalidUtf8),
|
||||
"allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen),
|
||||
|
|
779
src/args/arg.rs
779
src/args/arg.rs
File diff suppressed because it is too large
Load diff
|
@ -84,26 +84,13 @@ impl<'n, 'e> FlagBuilder<'n, 'e> {
|
|||
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self {
|
||||
if a.validator.is_some() {
|
||||
panic!("The argument '{}' has a validator set, yet was parsed as a flag. Ensure \
|
||||
.takes_value(true) or .index(u8) is set.", a.name)
|
||||
}
|
||||
if !a.is_set(ArgSettings::EmptyValues) {
|
||||
// Empty vals defaults to true, so if it's false it was manually set
|
||||
panic!("The argument '{}' cannot have empty_values() set because it is a flag. \
|
||||
Perhaps you mean't to set takes_value(true) as well?",
|
||||
a.name);
|
||||
}
|
||||
if a.is_set(ArgSettings::Required) {
|
||||
panic!("The argument '{}' cannot be required(true) because it has no index() or \
|
||||
takes_value(true)",
|
||||
a.name);
|
||||
}
|
||||
if a.possible_vals.is_some() {
|
||||
panic!("The argument '{}' cannot have a specific value set because it doesn't \
|
||||
assert!(a.validator.is_none(),
|
||||
format!("The argument '{}' has a validator set, yet was parsed as a flag. Ensure \
|
||||
.takes_value(true) or .index(u8) is set.", a.name));
|
||||
assert!(a.possible_vals.is_none(),
|
||||
format!("The argument '{}' cannot have a specific value set because it doesn't \
|
||||
have takes_value(true) set",
|
||||
a.name);
|
||||
}
|
||||
a.name));
|
||||
// No need to check for index() or takes_value() as that is handled above
|
||||
|
||||
let mut fb = FlagBuilder {
|
||||
|
|
|
@ -59,12 +59,10 @@ impl<'n, 'e> OptBuilder<'n, 'e> {
|
|||
}
|
||||
|
||||
pub fn from_arg(a: &Arg<'n, 'e>, reqs: &mut Vec<&'e str>) -> Self {
|
||||
debugln!("fn=from_arg;");
|
||||
if a.short.is_none() && a.long.is_none() {
|
||||
panic!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
|
||||
was supplied",
|
||||
a.name);
|
||||
}
|
||||
assert!(a.short.is_some() || a.long.is_some(),
|
||||
format!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
|
||||
was supplied", a.name));
|
||||
|
||||
// No need to check for .index() as that is handled above
|
||||
let mut ob = OptBuilder {
|
||||
name: a.name,
|
||||
|
|
|
@ -59,11 +59,9 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
|
|||
}
|
||||
|
||||
pub fn from_arg(a: &Arg<'n, 'e>, idx: u8, reqs: &mut Vec<&'e str>) -> Self {
|
||||
if a.short.is_some() || a.long.is_some() {
|
||||
panic!("Argument \"{}\" has conflicting requirements, both index() and short(), \
|
||||
or long(), were supplied",
|
||||
a.name);
|
||||
}
|
||||
assert!(a.short.is_none() || a.long.is_none(),
|
||||
format!("Argument \"{}\" has conflicting requirements, both index() and short(), \
|
||||
or long(), were supplied", a.name));
|
||||
|
||||
// Create the Positional Argument Builder with each HashSet = None to only
|
||||
// allocate
|
||||
|
|
|
@ -6,6 +6,7 @@ use vec_map::VecMap;
|
|||
|
||||
use args::{ArgMatches, MatchedArg, SubCommand};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct ArgMatcher<'a>(pub ArgMatches<'a>);
|
||||
|
||||
impl<'a> ArgMatcher<'a> {
|
||||
|
|
|
@ -8,57 +8,54 @@ use vec_map;
|
|||
|
||||
use args::SubCommand;
|
||||
use args::MatchedArg;
|
||||
use utf8::INVALID_UTF8;
|
||||
use INVALID_UTF8;
|
||||
|
||||
/// Used to get information about the arguments that where supplied to the program at runtime by
|
||||
/// the user. To get a new instance of this struct you use `.get_matches()` of the `App` struct.
|
||||
///
|
||||
/// the user. New instances of this struct are obtained by using the `App::get_matches` family of
|
||||
/// methods.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// let matches = App::new("MyApp")
|
||||
/// // adding of arguments and configuration goes here...
|
||||
/// # .arg(Arg::with_name("config")
|
||||
/// # .long("config")
|
||||
/// # .required(true)
|
||||
/// # .takes_value(true))
|
||||
/// # .arg(Arg::with_name("debug")
|
||||
/// # .short("d")
|
||||
/// # .multiple(true))
|
||||
/// .get_matches();
|
||||
/// // if you had an argument named "output" that takes a value
|
||||
/// if let Some(o) = matches.value_of("output") {
|
||||
/// println!("Value for output: {}", o);
|
||||
/// .arg(Arg::with_name("out")
|
||||
/// .long("output")
|
||||
/// .required(true)
|
||||
/// .takes_value(true))
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .short("d")
|
||||
/// .multiple(true))
|
||||
/// .arg(Arg::with_name("cfg")
|
||||
/// .short("c")
|
||||
/// .takes_value(true))
|
||||
/// .get_matches(); // builds the instance of ArgMatches
|
||||
///
|
||||
/// // to get information about the "cfg" argument we created, such as the value supplied we use
|
||||
/// // various ArgMatches methods, such as ArgMatches::value_of
|
||||
/// if let Some(c) = matches.value_of("cfg") {
|
||||
/// println!("Value for -c: {}", c);
|
||||
/// }
|
||||
///
|
||||
/// // If you have a required argument you can call .unwrap() because the program will exit long
|
||||
/// // before this point if the user didn't specify it at runtime.
|
||||
/// println!("Config file: {}", matches.value_of("config").unwrap());
|
||||
/// // The ArgMatches::value_of method returns an Option because the user may not have supplied
|
||||
/// // that argument at runtime. But if we specified that the argument was "required" as we did
|
||||
/// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually
|
||||
/// // used at runtime.
|
||||
/// println!("Value for --output: {}", matches.value_of("out").unwrap());
|
||||
///
|
||||
/// // You can check the presence of an argument
|
||||
/// if matches.is_present("debug") {
|
||||
/// if matches.is_present("out") {
|
||||
/// // Another way to check if an argument was present, or if it occurred multiple times is to
|
||||
/// // use occurrences_of() which returns 0 if an argument isn't found at runtime, or the
|
||||
/// // number of times that it occurred, if it was. To allow an argument to appear more than
|
||||
/// // once, you must use the .multiple(true) method, otherwise it will only return 1 or 0.
|
||||
/// if matches.occurrences_of("debug") > 2 {
|
||||
/// println!("Debug mode is REALLY on");
|
||||
/// println!("Debug mode is REALLY on, don't be crazy");
|
||||
/// } else {
|
||||
/// println!("Debug mode kind of on");
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // You can get the sub-matches of a particular subcommand (in this case "test")
|
||||
/// // If "test" had it's own "-l" flag you could check for it's presence accordingly
|
||||
/// if let Some(ref matches) = matches.subcommand_matches("test") {
|
||||
/// if matches.is_present("list") {
|
||||
/// println!("Printing testing lists...");
|
||||
/// } else {
|
||||
/// println!("Not printing testing lists...");
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArgMatches<'a> {
|
||||
#[doc(hidden)]
|
||||
|
@ -80,15 +77,6 @@ impl<'a> Default for ArgMatches<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ArgMatches<'a> {
|
||||
/// Creates a new instance of `ArgMatches`. This ins't called directly, but
|
||||
/// through the `.get_matches()` method of `App`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// let matches = App::new("myprog").get_matches();
|
||||
/// ```
|
||||
#[doc(hidden)]
|
||||
pub fn new() -> Self { ArgMatches { ..Default::default() } }
|
||||
|
||||
|
@ -97,11 +85,15 @@ impl<'a> ArgMatches<'a> {
|
|||
/// it returns `None`.
|
||||
///
|
||||
/// *NOTE:* If getting a value for an option or positional argument that allows multiples,
|
||||
/// prefer `values_of()` as `value_of()` will only return the _*first*_ value.
|
||||
/// prefer `values_of()` as `value_of()` will only return the *first* value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method will `panic!` if the value contains invalid UTF-8 code points.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// let m = App::new("myapp")
|
||||
/// .arg(Arg::with_name("output")
|
||||
|
@ -119,12 +111,12 @@ impl<'a> ArgMatches<'a> {
|
|||
None
|
||||
}
|
||||
|
||||
/// Gets the lossy value of a specific argument If the option wasn't present at runtime
|
||||
/// Gets the lossy value of a specific argument. If the argument wasn't present at runtime
|
||||
/// it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those
|
||||
/// invalid points will be replaced with `\u{FFFD}`
|
||||
///
|
||||
/// *NOTE:* If getting a value for an option or positional argument that allows multiples,
|
||||
/// prefer `lossy_values_of()` as `lossy_value_of()` will only return the _*first*_ value.
|
||||
/// prefer `lossy_values_of()` as `lossy_value_of()` will only return the *first* value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -149,17 +141,14 @@ impl<'a> ArgMatches<'a> {
|
|||
None
|
||||
}
|
||||
|
||||
/// Gets the OS version of a string value of a specific argument If the option wasn't present at
|
||||
/// runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, regardless
|
||||
/// of whether or not they contain valid UTF-8 code points. Since `String`s in Rust are
|
||||
/// garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for example) may
|
||||
/// contain invalid UTF-8 code points. This would cause a `panic!` or only the abiltiy to get a
|
||||
/// lossy version of the file name (i.e. one where the invalid code points were replaced with
|
||||
/// `\u{FFFD}`). This method returns an `OsString` which allows one to represent those strings
|
||||
/// which rightfully contain invalid UTF-8.
|
||||
/// Gets the OS version of a string value of a specific argument. If the option wasn't present
|
||||
/// at runtime it returns `None`. An OS value on Unix-like systems is any series of bytes,
|
||||
/// regardless of whether or not they contain valid UTF-8 code points. Since `String`s in Rust
|
||||
/// are garunteed to be valid UTF-8, a valid filename on a Unix system as an argument value may
|
||||
/// contain invalid UTF-8 code points.
|
||||
///
|
||||
/// *NOTE:* If getting a value for an option or positional argument that allows multiples,
|
||||
/// prefer `os_values_of()` as `os_value_of()` will only return the _*first*_ value.
|
||||
/// prefer `os_values_of()` as `os_value_of()` will only return the *first* value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -173,30 +162,33 @@ impl<'a> ArgMatches<'a> {
|
|||
/// .get_matches_from(vec![OsString::from("myprog"),
|
||||
/// // "Hi {0xe9}!"
|
||||
/// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
|
||||
/// assert_eq!(&*m.os_value_of("arg").unwrap().as_bytes(), &[b'H', b'i', b' ', 0xe9, b'!']);
|
||||
/// assert_eq!(&*m.os_value_of("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
|
||||
/// ```
|
||||
pub fn os_value_of<S: AsRef<str>>(&self, name: S) -> Option<&OsStr> {
|
||||
self.args.get(name.as_ref()).map_or(None, |arg| arg.vals.values().nth(0).map(|v| v.as_os_str()))
|
||||
}
|
||||
|
||||
/// Gets the values of a specific option or positional argument in a vector (i.e. an argument
|
||||
/// that takes multiple values at runtime). If the option wasn't present at runtime it
|
||||
/// returns `None`
|
||||
/// Gets an Iterator of values of a specific argument (i.e. an argument that takes multiple
|
||||
/// values at runtime). If the option wasn't present at runtime it returns `None`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method will panic if any of the values contain invalid UTF-8 code points.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// # let matches = App::new("myapp")
|
||||
/// # .arg(Arg::with_name("output").takes_value(true)).get_matches();
|
||||
/// // If the program had option "-c" that took a value and was run
|
||||
/// // via "myapp -o some -o other -o file"
|
||||
/// // values_of() would return a [&str; 3] ("some", "other", "file")
|
||||
/// if let Some(os) = matches.values_of("output") {
|
||||
/// for o in os {
|
||||
/// println!("A value for output: {}", o);
|
||||
/// }
|
||||
/// }
|
||||
/// let m = App::new("myprog")
|
||||
/// .arg(Arg::with_name("output")
|
||||
/// .multiple(true)
|
||||
/// .short("o")
|
||||
/// .takes_value(true))
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "-o", "val1", "val2", "val3"
|
||||
/// ]);
|
||||
/// let vals: Vec<&str> = m.values_of("output").unwrap().collect();
|
||||
/// assert_eq!(vals, ["val1", "val2", "val3"]);
|
||||
/// ```
|
||||
pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>> {
|
||||
if let Some(ref arg) = self.args.get(name.as_ref()) {
|
||||
|
@ -241,10 +233,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// at runtime it returns `None`. An OS value on Unix-like systems is any series of bytes,
|
||||
/// regardless of whether or not they contain valid UTF-8 code points. Since `String`s in Rust
|
||||
/// are garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for
|
||||
/// example) may contain invalid UTF-8 code points. This would cause a `panic!` or only the
|
||||
/// abiltiy to get a lossy version of the file name (i.e. one where the invalid code points
|
||||
/// were replaced with `\u{FFFD}`). This method returns an `OsString` which allows one to
|
||||
/// represent those strings which rightfully contain invalid UTF-8.
|
||||
/// example) may contain invalid UTF-8 code points.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -275,18 +264,20 @@ impl<'a> ArgMatches<'a> {
|
|||
None
|
||||
}
|
||||
|
||||
/// Returns if an argument was present at runtime.
|
||||
///
|
||||
/// Returns `true` if an argument was present at runtime, otherwise `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// # let matches = App::new("myapp")
|
||||
/// # .arg(Arg::with_name("output").takes_value(true)).get_matches();
|
||||
/// if matches.is_present("output") {
|
||||
/// println!("The output argument was used!");
|
||||
/// }
|
||||
/// let m = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .short("d"))
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "-d"
|
||||
/// ]);
|
||||
///
|
||||
/// assert!(m.is_present("debug"));
|
||||
/// ```
|
||||
pub fn is_present<S: AsRef<str>>(&self, name: S) -> bool {
|
||||
if let Some(ref sc) = self.subcommand {
|
||||
|
@ -297,60 +288,132 @@ impl<'a> ArgMatches<'a> {
|
|||
self.args.contains_key(name.as_ref())
|
||||
}
|
||||
|
||||
/// Returns the number of occurrences of an option, flag, or positional argument at runtime.
|
||||
/// If an argument isn't present it will return `0`. Can be used on arguments which *don't*
|
||||
/// allow multiple occurrences, but will obviously only return `0` or `1`.
|
||||
/// Returns the number of times an argument was used at runtime. If an argument isn't present
|
||||
/// it will return `0`.
|
||||
///
|
||||
/// **NOTE:** This returns the number of times the argument was used, *not* the number of
|
||||
/// values. For example, `-o val1 val2 val3 -o val4` would return `2`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// # let matches = App::new("myapp")
|
||||
/// # .arg(Arg::with_name("output").takes_value(true)).get_matches();
|
||||
/// if matches.occurrences_of("debug") > 1 {
|
||||
/// println!("Debug mode is REALLY on");
|
||||
/// } else {
|
||||
/// println!("Debug mode kind of on");
|
||||
/// }
|
||||
/// let m = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .short("d")
|
||||
/// .multiple(true))
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "-d", "-d", "-d"
|
||||
/// ]);
|
||||
///
|
||||
/// assert_eq!(m.occurrences_of("debug"), 3);
|
||||
/// ```
|
||||
///
|
||||
/// This next example shows that counts actual uses of the argument, not just `-`'s
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// let m = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .short("d")
|
||||
/// .multiple(true))
|
||||
/// .arg(Arg::with_name("flag")
|
||||
/// .short("f"))
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "-ddfd"
|
||||
/// ]);
|
||||
///
|
||||
/// assert_eq!(m.occurrences_of("debug"), 3);
|
||||
/// assert_eq!(m.occurrences_of("flag"), 1);
|
||||
/// ```
|
||||
pub fn occurrences_of<S: AsRef<str>>(&self, name: S) -> u8 {
|
||||
self.args.get(name.as_ref()).map_or(0, |a| a.occurs)
|
||||
}
|
||||
|
||||
/// Returns the `ArgMatches` for a particular subcommand or None if the subcommand wasn't
|
||||
/// present at runtime.
|
||||
///
|
||||
/// Because subcommands are essentially "sub-apps" they have their own `ArgMatches` as well.
|
||||
/// This method returns the `ArgMatches` for a particular subcommand or None if the subcommand
|
||||
/// wasn't present at runtime.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let app_matches = App::new("myapp")
|
||||
/// # .subcommand(SubCommand::with_name("test")).get_matches();
|
||||
/// if let Some(matches) = app_matches.subcommand_matches("test") {
|
||||
/// // Use matches as normal
|
||||
/// let app_m = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .short("d"))
|
||||
/// .subcommand(SubCommand::with_name("test")
|
||||
/// .arg(Arg::with_name("opt")
|
||||
/// .long("option")
|
||||
/// .takes_value(true)))
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "-d", "test", "--option", "val"
|
||||
/// ]);
|
||||
///
|
||||
/// // Both parent commands, and child subcommands can have arguments present at the same times
|
||||
/// assert!(app_m.is_present("debug"));
|
||||
///
|
||||
/// // Get the subcommand's ArgMatches instance
|
||||
/// if let Some(sub_m) = app_m.subcommand_matches("test") {
|
||||
/// // Use the struct like normal
|
||||
/// assert_eq!(sub_m.value_of("opt"), Some("val"));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn subcommand_matches<S: AsRef<str>>(&self, name: S) -> Option<&ArgMatches<'a>> {
|
||||
self.subcommand.as_ref().map(|s| if s.name == name.as_ref() { Some(&s.matches) } else { None } ).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the name of the subcommand used of the parent `App`, or `None` if one wasn't found
|
||||
/// Because subcommands are essentially "sub-apps" they have their own `ArgMatches` as well.
|
||||
/// But simply getting the sub-`ArgMatches` doesn't help much if we don't also know which
|
||||
/// subcommand was actually used. This method returns the name of the subcommand that was used
|
||||
/// at runtime, or `None` if one wasn't.
|
||||
///
|
||||
/// *NOTE*: Only a single subcommand may be present per `App` at runtime, does *NOT* check for
|
||||
/// the name of sub-subcommand's names
|
||||
/// *NOTE*: Subcommands form a hierarchy, where multiple subcommands can be used at runtime,
|
||||
/// but only a single subcommand from any group of sibling commands may used at once.
|
||||
///
|
||||
/// An ASCII art depiction may help explain this better...Using a fictional version of `git` as
|
||||
/// the demo subject. Imagine the following are all subcommands of `git` (note, the author is
|
||||
/// aware these aren't actually all subcommands in the real `git` interface, but it makes
|
||||
/// explaination easier)
|
||||
///
|
||||
/// ```ignore
|
||||
/// Top Level App (git) TOP
|
||||
/// |
|
||||
/// -----------------------------------------
|
||||
/// / | \ \
|
||||
/// clone push add commit LEVEL 1
|
||||
/// | / \ / \ |
|
||||
/// url origin remote ref name message LEVEL 2
|
||||
/// / /\
|
||||
/// path remote local LEVEL 3
|
||||
/// ```
|
||||
///
|
||||
/// Given the above fictional subcommand hierarchy, valid runtime uses would be (not an all
|
||||
/// inclusive list, and not including argument options per command for brevity and clarity):
|
||||
///
|
||||
/// ```ignore
|
||||
/// $ git clone url
|
||||
/// $ git push origin path
|
||||
/// $ git add ref local
|
||||
/// $ git commit message
|
||||
/// ```
|
||||
///
|
||||
/// Notice only one command per "level" may be used. You could not, for example, do `$ git
|
||||
/// clone url push origin path`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let app_matches = App::new("myapp")
|
||||
/// # .subcommand(SubCommand::with_name("test")).get_matches();
|
||||
/// match app_matches.subcommand_name() {
|
||||
/// Some("test") => {}, // test was used
|
||||
/// Some("config") => {}, // config was used
|
||||
/// let app_m = App::new("git")
|
||||
/// .subcommand(SubCommand::with_name("clone"))
|
||||
/// .subcommand(SubCommand::with_name("push"))
|
||||
/// .subcommand(SubCommand::with_name("commit"))
|
||||
/// .get_matches();
|
||||
///
|
||||
/// match app_m.subcommand_name() {
|
||||
/// Some("clone") => {}, // clone was used
|
||||
/// Some("push") => {}, // push was used
|
||||
/// Some("commit") => {}, // commit was used
|
||||
/// _ => {}, // Either no subcommand or one not tested for...
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -358,20 +421,48 @@ impl<'a> ArgMatches<'a> {
|
|||
self.subcommand.as_ref().map(|sc| &sc.name[..])
|
||||
}
|
||||
|
||||
/// Returns the name and `ArgMatches` of the subcommand used at runtime or ("", None) if one
|
||||
/// wasn't found.
|
||||
///
|
||||
/// This brings together `ArgMatches::subcommand_matches` and `ArgMatches::subcommand_name` by
|
||||
/// returning a tuple with both pieces of information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let app_matches = App::new("myapp")
|
||||
/// # .subcommand(SubCommand::with_name("test")).get_matches();
|
||||
/// match app_matches.subcommand() {
|
||||
/// ("test", Some(matches)) => {}, // test was used
|
||||
/// ("config", Some(matches)) => {}, // config was used
|
||||
/// _ => {}, // Either no subcommand or one not tested for...
|
||||
/// let app_m = App::new("git")
|
||||
/// .subcommand(SubCommand::with_name("clone"))
|
||||
/// .subcommand(SubCommand::with_name("push"))
|
||||
/// .subcommand(SubCommand::with_name("commit"))
|
||||
/// .get_matches();
|
||||
///
|
||||
/// match app_m.subcommand() {
|
||||
/// ("clone", Some(sub_m)) => {}, // clone was used
|
||||
/// ("push", Some(sub_m)) => {}, // push was used
|
||||
/// ("commit", Some(sub_m)) => {}, // commit was used
|
||||
/// _ => {}, // Either no subcommand or one not tested for...
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Another useful scenario is when you want to support third party, or external, subcommands.
|
||||
/// In these cases you can't know the subcommand name ahead of time, so use a variable instead
|
||||
/// with pattern matching!
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, AppSettings};
|
||||
/// // Assume there is an external subcommand named "subcmd"
|
||||
/// let app_m = App::new("myprog")
|
||||
/// .setting(AppSettings::AllowExternalSubcommands)
|
||||
/// .get_matches_from(vec![
|
||||
/// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
|
||||
/// ]);
|
||||
///
|
||||
/// // All trailing arguments will be stored under the subcommand's sub-matches using a value
|
||||
/// // of the runtime subcommand name (in this case "subcmd")
|
||||
/// match app_m.subcommand() {
|
||||
/// (external, Some(sub_m)) => {
|
||||
/// let ext_args: Vec<&str> = sub_m.values_of(external).unwrap().collect();
|
||||
/// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
|
||||
/// },
|
||||
/// _ => {},
|
||||
/// }
|
||||
/// ```
|
||||
pub fn subcommand(&self) -> (&str, Option<&ArgMatches<'a>>) {
|
||||
|
@ -380,14 +471,15 @@ impl<'a> ArgMatches<'a> {
|
|||
|
||||
/// Returns a string slice of the usage statement for the `App` (or `SubCommand`)
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let app_matches = App::new("myapp")
|
||||
/// # .subcommand(SubCommand::with_name("test")).get_matches();
|
||||
/// println!("{}",app_matches.usage());
|
||||
/// let app_m = App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches();
|
||||
///
|
||||
/// println!("{}", app_m.usage());
|
||||
/// ```
|
||||
pub fn usage(&self) -> &str {
|
||||
self.usage.as_ref().map_or("", |u| &u[..])
|
||||
|
|
|
@ -5,18 +5,18 @@ use std::fmt::{Debug, Formatter, Result};
|
|||
#[cfg(feature = "yaml")]
|
||||
use yaml_rust::Yaml;
|
||||
|
||||
/// `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.
|
||||
/// `ArgGroup`s are a family of related arguments and way for you to express, "Any of these
|
||||
/// arguments". By placing arguments in a logical group, you can create easier requirement and
|
||||
/// exclusion rules instead of having to list each argument 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).
|
||||
/// 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 parsing failure.
|
||||
///
|
||||
/// 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.
|
||||
/// You can also do things such as name an entire `ArgGroup` as a conflict or requirement for
|
||||
/// another argument, 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
|
||||
|
@ -28,19 +28,27 @@ use yaml_rust::Yaml;
|
|||
/// `--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.
|
||||
///
|
||||
/// Finally, you may use `ArgGroup`s to pull a value from a group of arguments when you don't care
|
||||
/// exaclty which argument was actually used at runtime.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// The following example demonstrates using an `ArgGroup` to ensure that one, and only one, of
|
||||
/// the arguments from the specified group is present at runtime.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// let _ = App::new("app")
|
||||
/// .args_from_usage("--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch")
|
||||
/// .group(ArgGroup::with_name("vers")
|
||||
/// .args(&["ver", "major", "minor","patch"])
|
||||
/// .required(true))
|
||||
/// # .get_matches();
|
||||
/// App::new("app")
|
||||
/// .args_from_usage(
|
||||
/// "--set-ver [ver] 'set the version manually'
|
||||
/// --major 'auto increase major'
|
||||
/// --minor 'auto increase minor'
|
||||
/// --patch 'auto increase patch'")
|
||||
/// .group(ArgGroup::with_name("vers")
|
||||
/// .args(&["set-ver", "major", "minor","patch"])
|
||||
/// .required(true))
|
||||
/// # ;
|
||||
/// ```
|
||||
pub struct ArgGroup<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: &'a str,
|
||||
|
@ -55,17 +63,16 @@ pub struct ArgGroup<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ArgGroup<'a> {
|
||||
/// Creates a new instance of `ArgGroup` using a unique string name.
|
||||
/// The name will only be used by the library consumer and not displayed to the use.
|
||||
/// Creates a new instance of `ArgGroup` using a unique string name. The name will be used to
|
||||
/// get values from the group or refer to the group inside of conflict and requirement rules.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// ArgGroup::with_name("config")
|
||||
/// # ).get_matches();
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn with_name(n: &'a str) -> Self {
|
||||
ArgGroup {
|
||||
name: n,
|
||||
|
@ -104,6 +111,12 @@ impl<'a> ArgGroup<'a> {
|
|||
}
|
||||
a
|
||||
}
|
||||
"arg" => {
|
||||
if let Some(ys) = v.as_str().unwrap() {
|
||||
a = a.arg(ys);
|
||||
}
|
||||
a
|
||||
}
|
||||
"requires" => {
|
||||
for ys in v.as_vec().unwrap() {
|
||||
if let Some(s) = ys.as_str() {
|
||||
|
@ -132,16 +145,16 @@ impl<'a> ArgGroup<'a> {
|
|||
|
||||
/// Adds an argument to this group by name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .arg("config")
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{App, ArgGroup, Arg};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .arg("config")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn arg(mut self, n: &'a str) -> Self {
|
||||
assert!(self.name != n,
|
||||
"ArgGroup '{}' can not have same name as arg inside it",
|
||||
|
@ -152,16 +165,17 @@ impl<'a> ArgGroup<'a> {
|
|||
|
||||
/// Adds multiple arguments to this group by name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .args(&["config", "input", "output"])
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{ArgGroup, Arg};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .args(&["config", "input"])
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn args(mut self, ns: &[&'a str]) -> Self {
|
||||
for n in ns {
|
||||
self = self.arg(n);
|
||||
|
@ -169,21 +183,23 @@ impl<'a> ArgGroup<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the requirement of this group. A required group will be displayed in the usage string
|
||||
/// Sets the group as required or not. A required group will be displayed in the usage string
|
||||
/// of the application in the format `[arg|arg2|arg3]`. A required `ArgGroup` simply states
|
||||
/// that one, and only one argument from this group *must* be present at runtime (unless
|
||||
/// conflicting with another argument).
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .required(true)
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{Arg, ArgGroup};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("cfg")
|
||||
/// .args(&["config", "input"])
|
||||
/// .required(true)
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn required(mut self, r: bool) -> Self {
|
||||
self.required = r;
|
||||
self
|
||||
|
@ -195,16 +211,21 @@ impl<'a> ArgGroup<'a> {
|
|||
///
|
||||
/// **NOTE:** The name provided may be an argument, or group name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .requires("config")
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ArgGroup};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .args(&["config", "input"])
|
||||
/// // ...
|
||||
/// # ;
|
||||
/// ArgGroup::with_name("other_group")
|
||||
/// .requires("files")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn requires(mut self, n: &'a str) -> Self {
|
||||
if let Some(ref mut reqs) = self.requires {
|
||||
reqs.push(n);
|
||||
|
@ -220,16 +241,21 @@ impl<'a> ArgGroup<'a> {
|
|||
///
|
||||
/// **NOTE:** The names provided may be an argument, or group name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .requires_all(&["config", "input"])
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ArgGroup};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .args(&["config", "input"])
|
||||
/// // ...
|
||||
/// # ;
|
||||
/// ArgGroup::with_name("other_group")
|
||||
/// .requires_all(&["config", "input"]) // No different than saying, .requires("files")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn requires_all(mut self, ns: &[&'a str]) -> Self {
|
||||
for n in ns {
|
||||
self = self.requires(n);
|
||||
|
@ -237,22 +263,27 @@ impl<'a> ArgGroup<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the exclusion rules of this group. Exclusion rules function just like argument
|
||||
/// exclusion rules, you can name other arguments or groups that must not be present when one
|
||||
/// of the arguments from this group are used.
|
||||
/// Sets the exclusion rules of this group. Exclusion (aka conflict) rules function just like
|
||||
/// argument exclusion rules, you can name other arguments or groups that must not be present
|
||||
/// when one of the arguments from this group are used.
|
||||
///
|
||||
/// **NOTE:** The name provided may be an argument, or group name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .conflicts_with("config")
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ArgGroup};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .args(&["config", "input"])
|
||||
/// // ...
|
||||
/// # ;
|
||||
/// ArgGroup::with_name("other_group")
|
||||
/// .conflicts_with("files")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn conflicts_with(mut self, n: &'a str) -> Self {
|
||||
if let Some(ref mut confs) = self.conflicts {
|
||||
confs.push(n);
|
||||
|
@ -268,16 +299,21 @@ impl<'a> ArgGroup<'a> {
|
|||
///
|
||||
/// **NOTE:** The names provided may be an argument, or group name
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, ArgGroup};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .group(
|
||||
/// # ArgGroup::with_name("config")
|
||||
/// .conflicts_with_all(&["config", "input"])
|
||||
/// # ).get_matches();
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ArgGroup};
|
||||
/// let cfg_arg = Arg::with_name("config");
|
||||
/// let in_arg = Arg::with_name("input");
|
||||
/// // ...
|
||||
/// ArgGroup::with_name("files")
|
||||
/// .args(&["config", "input"])
|
||||
/// // ...
|
||||
/// # ;
|
||||
/// ArgGroup::with_name("other_group")
|
||||
/// .conflicts_with_all(&["files", "input"]) // same as saying, conflicts_with("files")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn conflicts_with_all(mut self, ns: &[&'a str]) -> Self {
|
||||
for n in ns {
|
||||
self = self.conflicts_with(n);
|
||||
|
|
|
@ -13,6 +13,7 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArgFlags(Flags);
|
||||
|
||||
|
|
|
@ -4,25 +4,25 @@ use yaml_rust::Yaml;
|
|||
use App;
|
||||
use ArgMatches;
|
||||
|
||||
/// The abstract representation of a command line subcommand used by the consumer of the library.
|
||||
/// The abstract representation of a command line subcommand.
|
||||
///
|
||||
///
|
||||
/// This struct is used by the library consumer and describes all the valid options of the
|
||||
/// subcommand for their program. SubCommands are treated like "sub apps" and contain all the same
|
||||
/// possibilities (such as their own arguments and subcommands).
|
||||
/// This struct describes all the valid options of the subcommand for the program. Subcommands are
|
||||
/// essentially "sub apps" and contain all the same possibilities (such as their own arguments,
|
||||
/// subcommands, and settings).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .subcommand(
|
||||
/// SubCommand::with_name("config")
|
||||
/// .about("Used for configuration")
|
||||
/// .arg(Arg::with_name("config_file")
|
||||
/// .help("The configuration file to use")
|
||||
/// .index(1))
|
||||
/// # ).get_matches();
|
||||
/// App::new("myprog")
|
||||
/// .subcommand(
|
||||
/// SubCommand::with_name("config")
|
||||
/// .about("Used for configuration")
|
||||
/// .arg(Arg::with_name("config_file")
|
||||
/// .help("The configuration file to use")
|
||||
/// .index(1)))
|
||||
/// # ;
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubCommand<'a> {
|
||||
#[doc(hidden)]
|
||||
|
@ -32,16 +32,17 @@ pub struct SubCommand<'a> {
|
|||
}
|
||||
|
||||
impl<'a> SubCommand<'a> {
|
||||
/// Creates a new instance of a subcommand requiring a name. Will be displayed
|
||||
/// Creates a new instance of a subcommand requiring a name. The name will be displayed
|
||||
/// to the user when they print version or help and usage information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, SubCommand};
|
||||
/// # let prog = App::new("myprog").subcommand(
|
||||
/// SubCommand::with_name("config")
|
||||
/// # ).get_matches();
|
||||
/// App::new("myprog")
|
||||
/// .subcommand(
|
||||
/// SubCommand::with_name("config"))
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn with_name<'b>(name: &str) -> App<'a, 'b> {
|
||||
App::new(name)
|
||||
|
|
|
@ -10,9 +10,10 @@ use fmt::Format;
|
|||
use suggestions;
|
||||
use args::any_arg::AnyArg;
|
||||
|
||||
/// Short hand for result type
|
||||
pub type Result<T> = StdResult<T, Error>;
|
||||
|
||||
/// Command line argument parser error
|
||||
/// Command line argument parser kind of error
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum ErrorKind {
|
||||
/// Occurs when an `Arg` has a set of possible values, and the user provides a value which
|
||||
|
@ -20,7 +21,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("speed")
|
||||
|
@ -35,7 +36,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::from_usage("--flag 'some flag'"))
|
||||
|
@ -50,7 +51,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind, SubCommand};
|
||||
/// let result = App::new("myprog")
|
||||
/// .subcommand(SubCommand::with_name("config")
|
||||
|
@ -58,7 +59,7 @@ pub enum ErrorKind {
|
|||
/// .arg(Arg::with_name("config_file")
|
||||
/// .help("The configuration file to use")
|
||||
/// .index(1)))
|
||||
/// .get_matches_from_safe(vec!["myprog", "other"]);
|
||||
/// .get_matches_from_safe(vec!["myprog", "confi"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind, ErrorKind::InvalidSubcommand);
|
||||
/// ```
|
||||
|
@ -67,14 +68,15 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// let res = App::new("myprog")
|
||||
/// .arg(Arg::with_name("color")
|
||||
/// .long("color")
|
||||
/// .empty_values(false))
|
||||
/// .get_matches_from_safe(vec!["myprog", "--debug", ""]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind, ErrorKind::EmptyValue);
|
||||
/// .get_matches_from_safe(vec!["myprog", "--color="]);
|
||||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
|
||||
/// ```
|
||||
EmptyValue,
|
||||
/// Occurs when the user provides a value for an argument with a custom validation and the
|
||||
|
@ -82,7 +84,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// fn is_numeric(val: String) -> Result<(), String> {
|
||||
/// match val.parse::<i64>() {
|
||||
|
@ -104,14 +106,13 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("some_opt")
|
||||
/// .long("opt")
|
||||
/// .takes_value(true)
|
||||
/// .arg(Arg::with_name("arg")
|
||||
/// .multiple(true)
|
||||
/// .max_values(2))
|
||||
/// .get_matches_from_safe(vec!["myprog", "--opt", "too", "many", "values"]);
|
||||
/// .get_matches_from_safe(vec!["myprog", "too", "many", "values"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind, ErrorKind::TooManyValues);
|
||||
/// ```
|
||||
|
@ -121,7 +122,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("some_opt")
|
||||
|
@ -133,27 +134,29 @@ pub enum ErrorKind {
|
|||
/// ```
|
||||
TooFewValues,
|
||||
/// Occurs when the user provides a different number of values for an argument than what's
|
||||
/// been defined by setting `Arg::number_of_values`
|
||||
/// been defined by setting `Arg::number_of_values` or than was implicitly set by
|
||||
/// `Arg::value_names`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("some_opt")
|
||||
/// .long("opt")
|
||||
/// .takes_value(true)
|
||||
/// .number_of_values(2))
|
||||
/// .get_matches_from_safe(vec!["myprog", "--opt", "wrong", "number", "of", "vals"]);
|
||||
/// .get_matches_from_safe(vec!["myprog", "--opt", "wrong"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind, ErrorKind::WrongNumberOfValues);
|
||||
/// ```
|
||||
WrongNumberOfValues,
|
||||
/// Occurs when the user provides two values which conflict and can't be used together.
|
||||
/// Occurs when the user provides two values which conflict with each other and can't be used
|
||||
/// together.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
|
@ -170,7 +173,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
|
@ -185,17 +188,17 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg, AppSettings, ErrorKind, SubCommand};
|
||||
/// let result = App::new("myprog")
|
||||
/// ```rust
|
||||
/// # use clap::{App, AppSettings, SubCommand, ErrorKind};
|
||||
/// let err = App::new("myprog")
|
||||
/// .setting(AppSettings::SubcommandRequired)
|
||||
/// .subcommand(SubCommand::with_name("config")
|
||||
/// .about("Used for configuration")
|
||||
/// .arg(Arg::with_name("config_file")
|
||||
/// .help("The configuration file to use")))
|
||||
/// .get_matches_from_safe(vec!["myprog"]);
|
||||
/// assert!(result.is_err());
|
||||
/// assert_eq!(result.unwrap_err().kind, ErrorKind::MissingSubcommand);
|
||||
/// .subcommand(SubCommand::with_name("test"))
|
||||
/// .get_matches_from_safe(vec![
|
||||
/// "myprog",
|
||||
/// ]);
|
||||
/// assert!(err.is_err());
|
||||
/// assert_eq!(err.unwrap_err().kind, ErrorKind::MissingSubcommand);
|
||||
/// # ;
|
||||
/// ```
|
||||
MissingSubcommand,
|
||||
/// Occurs when either an argument or subcommand is required, as defined by
|
||||
|
@ -203,7 +206,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, AppSettings, ErrorKind, SubCommand};
|
||||
/// let result = App::new("myprog")
|
||||
/// .setting(AppSettings::ArgRequiredElseHelp)
|
||||
|
@ -221,10 +224,11 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .arg(Arg::with_name("debug")
|
||||
/// .long("debug")
|
||||
/// .multiple(false))
|
||||
/// .get_matches_from_safe(vec!["myprog", "--debug", "--debug"]);
|
||||
/// assert!(result.is_err());
|
||||
|
@ -264,7 +268,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .get_matches_from_safe(vec!["myprog", "--help"]);
|
||||
|
@ -277,7 +281,7 @@ pub enum ErrorKind {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let result = App::new("myprog")
|
||||
/// .get_matches_from_safe(vec!["myprog", "--version"]);
|
||||
|
@ -289,9 +293,9 @@ pub enum ErrorKind {
|
|||
/// type `T`, but the argument you requested wasn't used. I.e. you asked for an argument with
|
||||
/// name `config` to be converted, but `config` wasn't used by the user.
|
||||
ArgumentNotFound,
|
||||
/// Represents an I/O error, typically white writing to stderr or stdout
|
||||
/// Represents an I/O error, typically while writing to `stderr` or `stdout`
|
||||
Io,
|
||||
/// Represents an Rust Display Format error, typically white writing to stderr or stdout
|
||||
/// Represents an Rust Display Format error, typically white writing to `stderr` or `stdout`
|
||||
Format,
|
||||
}
|
||||
|
||||
|
|
|
@ -675,7 +675,7 @@ pub use yaml_rust::YamlLoader;
|
|||
pub use args::{Arg, ArgGroup, ArgMatches, SubCommand, ArgSettings};
|
||||
pub use app::{App, AppSettings};
|
||||
pub use fmt::Format;
|
||||
pub use errors::{Error, ErrorKind};
|
||||
pub use errors::{Error, ErrorKind, Result};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
@ -685,8 +685,8 @@ mod usage_parser;
|
|||
mod fmt;
|
||||
mod suggestions;
|
||||
mod errors;
|
||||
mod utf8;
|
||||
mod osstringext;
|
||||
|
||||
const INTERNAL_ERROR_MSG: &'static str = "Fatal internal error. Please consider filing a bug \
|
||||
report at https://github.com/kbknapp/clap-rs/issues";
|
||||
const INVALID_UTF8: &'static str = "unexpected invalid UTF-8 code point";
|
||||
|
|
342
src/macros.rs
342
src/macros.rs
|
@ -1,81 +1,24 @@
|
|||
macro_rules! impl_settings {
|
||||
($n:ident, $($v:ident => $c:ident),+) => {
|
||||
pub fn set(&mut self, s: $n) {
|
||||
match s {
|
||||
$($n::$v => self.0.insert($c)),+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset(&mut self, s: $n) {
|
||||
match s {
|
||||
$($n::$v => self.0.remove($c)),+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_set(&self, s: $n) -> bool {
|
||||
match s {
|
||||
$($n::$v => self.0.contains($c)),+
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Convenience for writing to stderr thanks to https://github.com/BurntSushi
|
||||
macro_rules! wlnerr(
|
||||
($($arg:tt)*) => ({
|
||||
use std::io::{Write, stderr};
|
||||
writeln!(&mut stderr(), $($arg)*).ok();
|
||||
})
|
||||
);
|
||||
macro_rules! werr(
|
||||
($($arg:tt)*) => ({
|
||||
use std::io::{Write, stderr};
|
||||
write!(&mut stderr(), $($arg)*).ok();
|
||||
})
|
||||
);
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
#[cfg_attr(feature = "debug", macro_use)]
|
||||
mod debug_macros {
|
||||
macro_rules! debugln {
|
||||
($fmt:expr) => (println!(concat!("**DEBUG** ", $fmt)));
|
||||
($fmt:expr, $($arg:tt)*) => (println!(concat!("**DEBUG** ",$fmt), $($arg)*));
|
||||
}
|
||||
macro_rules! sdebugln {
|
||||
($fmt:expr) => (println!($fmt));
|
||||
($fmt:expr, $($arg:tt)*) => (println!($fmt, $($arg)*));
|
||||
}
|
||||
macro_rules! debug {
|
||||
($fmt:expr) => (print!(concat!("**DEBUG** ", $fmt)));
|
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!("**DEBUG** ",$fmt), $($arg)*));
|
||||
}
|
||||
macro_rules! sdebug {
|
||||
($fmt:expr) => (print!($fmt));
|
||||
($fmt:expr, $($arg:tt)*) => (print!($fmt, $($arg)*));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "debug"))]
|
||||
#[cfg_attr(not(feature = "debug"), macro_use)]
|
||||
mod debug_macros {
|
||||
macro_rules! debugln {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! sdebugln {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! sdebug {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! debug {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
}
|
||||
|
||||
/// A convienience macro for loading the YAML file at compile time (relative to the current file,
|
||||
/// like modules work). That YAML object can then be passed to this function.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The YAML file must be properly formatted or this function will panic!(). A good way to
|
||||
/// ensure this doesn't happen is to run your program with the `--help` switch. If this passes
|
||||
/// without error, you needn't worry because the YAML is properly formatted.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// The following example shows how to load a properly formatted YAML file to build an instnace
|
||||
/// of an `App` struct.
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use clap::App;
|
||||
/// let yml = load_yaml!("app.yml");
|
||||
/// let app = App::from_yaml(yml);
|
||||
///
|
||||
/// // continued logic goes here, such as `app.get_matches()` etc.
|
||||
/// ```
|
||||
#[cfg(feature = "yaml")]
|
||||
#[macro_export]
|
||||
macro_rules! load_yaml {
|
||||
|
@ -84,77 +27,11 @@ macro_rules! load_yaml {
|
|||
);
|
||||
}
|
||||
|
||||
// used in src/args/arg_builder/option.rs
|
||||
macro_rules! print_opt_help {
|
||||
($opt:ident, $spc:expr, $w:ident) => {
|
||||
debugln!("macro=print_opt_help!;");
|
||||
if let Some(h) = $opt.help {
|
||||
if h.contains("{n}") {
|
||||
let mut hel = h.split("{n}");
|
||||
if let Some(part) = hel.next() {
|
||||
try!(write!($w, "{}", part));
|
||||
}
|
||||
for part in hel {
|
||||
try!(write!($w, "\n"));
|
||||
write_spaces!($spc, $w);
|
||||
try!(write!($w, "{}", part));
|
||||
}
|
||||
} else {
|
||||
try!(write!($w, "{}", h));
|
||||
}
|
||||
if let Some(ref pv) = $opt.possible_vals {
|
||||
try!(write!($w, " [values:"));
|
||||
for pv_s in pv.iter() {
|
||||
try!(write!($w, " {}", pv_s));
|
||||
}
|
||||
try!(write!($w, "]"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Helper/deduplication macro for printing the correct number of spaces in help messages
|
||||
// used in:
|
||||
// src/args/arg_builder/*.rs
|
||||
// src/app/mod.rs
|
||||
macro_rules! write_spaces {
|
||||
($num:expr, $w:ident) => ({
|
||||
debugln!("macro=write_spaces!;");
|
||||
for _ in 0..$num {
|
||||
try!(write!($w, " "));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// convenience macro for remove an item from a vec
|
||||
macro_rules! vec_remove {
|
||||
($vec:expr, $to_rem:ident) => {
|
||||
debugln!("macro=write_spaces!;");
|
||||
{
|
||||
let mut ix = None;
|
||||
$vec.dedup();
|
||||
for (i, val) in $vec.iter().enumerate() {
|
||||
if val == $to_rem {
|
||||
ix = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(i) = ix {
|
||||
$vec.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
|
||||
/// This macro returns a `Result<T,String>` which allows you as the developer to decide
|
||||
/// what you'd like to do on a failed parse. There are two types of errors, parse failures
|
||||
/// and those where the argument wasn't present (such as a non-required argument).
|
||||
///
|
||||
/// You can use it to get a single value, or a `Vec<T>` with the `values_of()`
|
||||
///
|
||||
/// **NOTE:** Be cautious, as since this a macro invocation it's not exactly like
|
||||
/// standard syntax.
|
||||
/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr` from an
|
||||
/// argument value. This macro returns a `Result<T,String>` which allows you as the developer to
|
||||
/// decide what you'd like to do on a failed parse. There are two types of errors, parse failures
|
||||
/// and those where the argument wasn't present (such as a non-required argument). You can use
|
||||
/// it to get a single value, or a iterator as with the `ArgMatches::values_of`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -193,7 +70,7 @@ macro_rules! value_t {
|
|||
}
|
||||
|
||||
/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr` or
|
||||
/// exiting upon error.
|
||||
/// exiting upon error instead of returning a `Result`
|
||||
///
|
||||
/// **NOTE:** This macro is for backwards compatibility sake. Prefer
|
||||
/// `value_t!(/* ... */).unwrap_or_else(|e| e.exit())`
|
||||
|
@ -234,8 +111,8 @@ macro_rules! value_t_or_exit {
|
|||
};
|
||||
}
|
||||
|
||||
/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr`
|
||||
/// This macro returns a `clap::Result<T>` (`Result<T, clap::Error>`) which allows you as the
|
||||
/// Convenience macro getting a typed value `Vec<T>` where `T` implements `std::str::FromStr` This
|
||||
/// macro returns a `clap::Result<Vec<T>>` (`Result<Vec<T>, clap::Error>`) which allows you as the
|
||||
/// developer to decide what you'd like to do on a failed parse.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -289,11 +166,11 @@ macro_rules! values_t {
|
|||
};
|
||||
}
|
||||
|
||||
/// Convenience macro getting a typed value `T` where `T` implements `std::str::FromStr` or
|
||||
/// Convenience macro getting a typed value `Vec<T>` where `T` implements `std::str::FromStr` or
|
||||
/// exiting upon error.
|
||||
///
|
||||
/// **NOTE:** This macro is for backwards compatibility sake. Prefer
|
||||
/// `value_t!(/* ... */).unwrap_or_else(|e| e.exit())`
|
||||
/// `values_t!(/* ... */).unwrap_or_else(|e| e.exit())`
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -336,15 +213,15 @@ macro_rules! values_t_or_exit {
|
|||
}
|
||||
|
||||
/// Convenience macro to generate more complete enums with variants to be used as a type when
|
||||
/// parsing arguments. This enum also provides a `variants()` function which can be used to retrieve a
|
||||
/// `Vec<&'static str>` of the variant names.
|
||||
/// parsing arguments. This enum also provides a `variants()` function which can be used to
|
||||
/// retrieve a `Vec<&'static str>` of the variant names. As well as implementing `FromStr` and
|
||||
/// `Display` automatically.
|
||||
///
|
||||
/// **NOTE:** Case insensitivity is supported for ASCII characters
|
||||
/// **NOTE:** Case insensitivity is supported for ASCII characters only
|
||||
///
|
||||
/// **NOTE:** This macro automatically implements std::str::FromStr and std::fmt::Display
|
||||
///
|
||||
/// These enums support pub (or not) and use of the #[derive()] traits
|
||||
///
|
||||
/// **NOTE:** These enums support pub (or not) and uses of the #[derive()] traits
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -446,9 +323,11 @@ macro_rules! arg_enum {
|
|||
};
|
||||
}
|
||||
|
||||
/// Allows you pull the version for an from your Cargo.toml as MAJOR.MINOR.PATCH_PKGVERSION_PRE
|
||||
/// Allows you pull the version for an from your Cargo.toml at compile time as
|
||||
/// MAJOR.MINOR.PATCH_PKGVERSION_PRE
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// # #[macro_use]
|
||||
/// # extern crate clap;
|
||||
|
@ -466,7 +345,8 @@ macro_rules! crate_version {
|
|||
};
|
||||
}
|
||||
|
||||
/// App, Arg, SubCommand and Group builder macro (Usage-string like input)
|
||||
/// App, Arg, SubCommand and Group builder macro (Usage-string like input) must be compiled with
|
||||
/// the `unstable` feature in order to use.
|
||||
#[cfg_attr(feature = "nightly", macro_export)]
|
||||
macro_rules! clap_app {
|
||||
(@app ($builder:expr)) => { $builder };
|
||||
|
@ -587,3 +467,143 @@ macro_rules! clap_app {
|
|||
clap_app!{ @app ($crate::App::new(stringify!($name))) $($tail)*}
|
||||
}};
|
||||
}
|
||||
|
||||
// used in src/args/arg_builder/option.rs
|
||||
macro_rules! print_opt_help {
|
||||
($opt:ident, $spc:expr, $w:ident) => {
|
||||
debugln!("macro=print_opt_help!;");
|
||||
if let Some(h) = $opt.help {
|
||||
if h.contains("{n}") {
|
||||
let mut hel = h.split("{n}");
|
||||
if let Some(part) = hel.next() {
|
||||
try!(write!($w, "{}", part));
|
||||
}
|
||||
for part in hel {
|
||||
try!(write!($w, "\n"));
|
||||
write_spaces!($spc, $w);
|
||||
try!(write!($w, "{}", part));
|
||||
}
|
||||
} else {
|
||||
try!(write!($w, "{}", h));
|
||||
}
|
||||
if let Some(ref pv) = $opt.possible_vals {
|
||||
try!(write!($w, " [values:"));
|
||||
for pv_s in pv.iter() {
|
||||
try!(write!($w, " {}", pv_s));
|
||||
}
|
||||
try!(write!($w, "]"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_settings {
|
||||
($n:ident, $($v:ident => $c:ident),+) => {
|
||||
pub fn set(&mut self, s: $n) {
|
||||
match s {
|
||||
$($n::$v => self.0.insert($c)),+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset(&mut self, s: $n) {
|
||||
match s {
|
||||
$($n::$v => self.0.remove($c)),+
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_set(&self, s: $n) -> bool {
|
||||
match s {
|
||||
$($n::$v => self.0.contains($c)),+
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Convenience for writing to stderr thanks to https://github.com/BurntSushi
|
||||
macro_rules! wlnerr(
|
||||
($($arg:tt)*) => ({
|
||||
use std::io::{Write, stderr};
|
||||
writeln!(&mut stderr(), $($arg)*).ok();
|
||||
})
|
||||
);
|
||||
macro_rules! werr(
|
||||
($($arg:tt)*) => ({
|
||||
use std::io::{Write, stderr};
|
||||
write!(&mut stderr(), $($arg)*).ok();
|
||||
})
|
||||
);
|
||||
|
||||
#[cfg(feature = "debug")]
|
||||
#[cfg_attr(feature = "debug", macro_use)]
|
||||
mod debug_macros {
|
||||
macro_rules! debugln {
|
||||
($fmt:expr) => (println!(concat!("**DEBUG** ", $fmt)));
|
||||
($fmt:expr, $($arg:tt)*) => (println!(concat!("**DEBUG** ",$fmt), $($arg)*));
|
||||
}
|
||||
macro_rules! sdebugln {
|
||||
($fmt:expr) => (println!($fmt));
|
||||
($fmt:expr, $($arg:tt)*) => (println!($fmt, $($arg)*));
|
||||
}
|
||||
macro_rules! debug {
|
||||
($fmt:expr) => (print!(concat!("**DEBUG** ", $fmt)));
|
||||
($fmt:expr, $($arg:tt)*) => (print!(concat!("**DEBUG** ",$fmt), $($arg)*));
|
||||
}
|
||||
macro_rules! sdebug {
|
||||
($fmt:expr) => (print!($fmt));
|
||||
($fmt:expr, $($arg:tt)*) => (print!($fmt, $($arg)*));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "debug"))]
|
||||
#[cfg_attr(not(feature = "debug"), macro_use)]
|
||||
mod debug_macros {
|
||||
macro_rules! debugln {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! sdebugln {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! sdebug {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
macro_rules! debug {
|
||||
($fmt:expr) => ();
|
||||
($fmt:expr, $($arg:tt)*) => ();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper/deduplication macro for printing the correct number of spaces in help messages
|
||||
// used in:
|
||||
// src/args/arg_builder/*.rs
|
||||
// src/app/mod.rs
|
||||
macro_rules! write_spaces {
|
||||
($num:expr, $w:ident) => ({
|
||||
debugln!("macro=write_spaces!;");
|
||||
for _ in 0..$num {
|
||||
try!(write!($w, " "));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// convenience macro for remove an item from a vec
|
||||
macro_rules! vec_remove {
|
||||
($vec:expr, $to_rem:ident) => {
|
||||
debugln!("macro=write_spaces!;");
|
||||
{
|
||||
let mut ix = None;
|
||||
$vec.dedup();
|
||||
for (i, val) in $vec.iter().enumerate() {
|
||||
if val == $to_rem {
|
||||
ix = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(i) = ix {
|
||||
$vec.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ impl OsStrExt3 for OsStr {
|
|||
impl OsStrExt2 for OsStr {
|
||||
fn starts_with(&self, s: &[u8]) -> bool {
|
||||
let sab = self.as_bytes();
|
||||
if sab.is_empty() { return false; }
|
||||
for (i, b) in s.iter().enumerate() {
|
||||
if *b != sab[i] { return false; }
|
||||
}
|
||||
|
@ -78,6 +79,7 @@ impl OsStrExt2 for OsStr {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OsSplit<'a> {
|
||||
sep: u8,
|
||||
|
|
|
@ -17,6 +17,7 @@ enum UsageToken {
|
|||
Unknown
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct UsageParser<'a> {
|
||||
usage: &'a str,
|
||||
|
@ -60,7 +61,7 @@ impl<'a> UsageParser<'a> {
|
|||
}
|
||||
} else { break; }
|
||||
}
|
||||
if arg.name.is_empty() { panic!("No name found for Arg when parsing usage string: {}", self.usage) }
|
||||
assert!(!arg.name.is_empty(), format!("No name found for Arg when parsing usage string: {}", self.usage));
|
||||
let n_vals = if let Some(ref v) = arg.val_names { v.len() } else { 0 };
|
||||
if n_vals > 1 {
|
||||
arg.num_vals = Some(n_vals as u8);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub const INVALID_UTF8: &'static str = "unexpected invalid UTF-8 code point";
|
Loading…
Add table
Reference in a new issue