docs: updating docs for 2x release

This commit is contained in:
Kevin K 2016-01-26 14:02:10 -05:00
parent 609c06e119
commit f1876388a7
19 changed files with 1337 additions and 1085 deletions

View file

@ -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>,

View file

@ -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
///

View file

@ -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)

View file

@ -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),

File diff suppressed because it is too large Load diff

View file

@ -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 {

View file

@ -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,

View file

@ -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

View file

@ -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> {

View file

@ -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[..])

View file

@ -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);

View file

@ -13,6 +13,7 @@ bitflags! {
}
}
#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct ArgFlags(Flags);

View file

@ -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)

View file

@ -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,
}

View file

@ -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";

View file

@ -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);
}
}
}
}

View file

@ -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,

View file

@ -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);

View file

@ -1 +0,0 @@
pub const INVALID_UTF8: &'static str = "unexpected invalid UTF-8 code point";