aboutsummaryrefslogtreecommitdiff
path: root/clap/examples
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-01-07 11:18:04 +0000
committerDaniel Mueller <deso@posteo.net>2020-01-08 09:20:25 -0800
commit5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch)
tree55ab083fa8999d2ccbb5e921c1ffe52560dca152 /clap/examples
parent203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff)
downloadnitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.gz
nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.bz2
Add structopt dependency in version 0.3.7
This patch series replaces argparse with structopt in the argument handling code. As a first step, we need structopt as a dependency. Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296 Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7 Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1 Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2 Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3 Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2 Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3 Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393 Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7
Diffstat (limited to 'clap/examples')
-rw-r--r--clap/examples/01a_quick_example.rs79
-rw-r--r--clap/examples/01b_quick_example.rs93
-rw-r--r--clap/examples/01c_quick_example.rs75
-rw-r--r--clap/examples/02_apps.rs30
-rw-r--r--clap/examples/03_args.rs84
-rw-r--r--clap/examples/04_using_matches.rs54
-rw-r--r--clap/examples/05_flag_args.rs56
-rw-r--r--clap/examples/06_positional_args.rs56
-rw-r--r--clap/examples/07_option_args.rs71
-rw-r--r--clap/examples/08_subcommands.rs57
-rw-r--r--clap/examples/09_auto_version.rs29
-rw-r--r--clap/examples/10_default_values.rs40
-rw-r--r--clap/examples/11_only_specific_values.rs33
-rw-r--r--clap/examples/12_typed_values.rs50
-rw-r--r--clap/examples/13a_enum_values_automatic.rs68
-rw-r--r--clap/examples/13b_enum_values_manual.rs54
-rw-r--r--clap/examples/14_groups.rs87
-rw-r--r--clap/examples/15_custom_validator.rs37
-rw-r--r--clap/examples/16_app_settings.rs41
-rw-r--r--clap/examples/17_yaml.rs53
-rw-r--r--clap/examples/17_yaml.yml97
-rw-r--r--clap/examples/18_builder_macro.rs84
-rw-r--r--clap/examples/19_auto_authors.rs15
-rw-r--r--clap/examples/20_subcommands.rs143
-rw-r--r--clap/examples/21_aliases.rs39
-rw-r--r--clap/examples/22_stop_parsing_with_--.rs25
26 files changed, 1550 insertions, 0 deletions
diff --git a/clap/examples/01a_quick_example.rs b/clap/examples/01a_quick_example.rs
new file mode 100644
index 0000000..c7fa20f
--- /dev/null
+++ b/clap/examples/01a_quick_example.rs
@@ -0,0 +1,79 @@
+extern crate clap;
+
+use clap::{App, SubCommand};
+
+fn main() {
+
+ // This example shows how to create an application with several arguments using usage strings, which can be
+ // far less verbose that shown in 01b_QuickExample.rs, but is more readable. The downside is you cannot set
+ // the more advanced configuration options using this method (well...actually you can, you'll see ;) )
+ //
+ // The example below is functionally identical to the 01b_quick_example.rs and 01c_quick_example.rs
+ //
+ // Create an application with 5 possible arguments (2 auto generated) and 2 subcommands (1 auto generated)
+ // - A config file
+ // + Uses "-c filename" or "--config filename"
+ // - An output file
+ // + A positional argument (i.e. "$ myapp output_filename")
+ // - A debug flag
+ // + Uses "-d" or "--debug"
+ // + Allows multiple occurrences of such as "-dd" (for vary levels of debugging, as an example)
+ // - A help flag (automatically generated by clap)
+ // + Uses "-h" or "--help" (Only autogenerated if you do NOT specify your own "-h" or "--help")
+ // - A version flag (automatically generated by clap)
+ // + Uses "-V" or "--version" (Only autogenerated if you do NOT specify your own "-V" or "--version")
+ // - A subcommand "test" (subcommands behave like their own apps, with their own arguments
+ // + Used by "$ myapp test" with the following arguments
+ // > A list flag
+ // = Uses "-l" (usage is "$ myapp test -l"
+ // > A help flag (automatically generated by clap
+ // = Uses "-h" or "--help" (full usage "$ myapp test -h" or "$ myapp test --help")
+ // > A version flag (automatically generated by clap
+ // = Uses "-V" or "--version" (full usage "$ myapp test -V" or "$ myapp test --version")
+ // - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own)
+ // + Used by "$ myapp help" (same functionality as "-h" or "--help")
+ let matches = App::new("MyApp")
+ .version("1.0")
+ .author("Kevin K. <kbknapp@gmail.com>")
+ .about("Does awesome things")
+ .args_from_usage("-c, --config=[FILE] 'Sets a custom config file'
+ <output> 'Sets an optional output file'
+ -d... 'Turn debugging information on'")
+ .subcommand(SubCommand::with_name("test")
+ .about("does testing things")
+ .arg_from_usage("-l, --list 'lists test values'"))
+ .get_matches();
+
+ // You can check the value provided by positional arguments, or option arguments
+ if let Some(o) = matches.value_of("output") {
+ println!("Value for output: {}", o);
+ }
+
+ if let Some(c) = matches.value_of("config") {
+ println!("Value for config: {}", c);
+ }
+
+ // You can see how many times a particular flag or argument occurred
+ // Note, only flags can have multiple occurrences
+ match matches.occurrences_of("d") {
+ 0 => println!("Debug mode is off"),
+ 1 => println!("Debug mode is kind of on"),
+ 2 => println!("Debug mode is on"),
+ 3 | _ => println!("Don't be crazy"),
+ }
+
+ // You can check for the existence of subcommands, and if found use their
+ // matches just as you would the top level app
+ if let Some(matches) = matches.subcommand_matches("test") {
+ // "$ myapp test" was run
+ if matches.is_present("list") {
+ // "$ myapp test -l" was run
+ println!("Printing testing lists...");
+ } else {
+ println!("Not printing testing lists...");
+ }
+ }
+
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/01b_quick_example.rs b/clap/examples/01b_quick_example.rs
new file mode 100644
index 0000000..7f455a8
--- /dev/null
+++ b/clap/examples/01b_quick_example.rs
@@ -0,0 +1,93 @@
+extern crate clap;
+
+use clap::{App, Arg, SubCommand};
+
+fn main() {
+
+ // This method shows the traditional, and slightly more configurable way to set up arguments. This method is
+ // more verbose, but allows setting more configuration options, and even supports easier dynamic generation.
+ //
+ // The example below is functionally identical to the 01a_quick_example.rs and 01c_quick_example.rs
+ //
+ // *NOTE:* You can actually achieve the best of both worlds by using Arg::from_usage() (instead of Arg::with_name())
+ // and *then* setting any additional properties.
+ //
+ // Create an application with 5 possible arguments (2 auto generated) and 2 subcommands (1 auto generated)
+ // - A config file
+ // + Uses "-c filename" or "--config filename"
+ // - An output file
+ // + A positional argument (i.e. "$ myapp output_filename")
+ // - A debug flag
+ // + Uses "-d" or "--debug"
+ // + Allows multiple occurrences of such as "-dd" (for vary levels of debugging, as an example)
+ // - A help flag (automatically generated by clap)
+ // + Uses "-h" or "--help" (Only autogenerated if you do NOT specify your own "-h" or "--help")
+ // - A version flag (automatically generated by clap)
+ // + Uses "-V" or "--version" (Only autogenerated if you do NOT specify your own "-V" or "--version")
+ // - A subcommand "test" (subcommands behave like their own apps, with their own arguments
+ // + Used by "$ myapp test" with the following arguments
+ // > A list flag
+ // = Uses "-l" (usage is "$ myapp test -l"
+ // > A help flag (automatically generated by clap
+ // = Uses "-h" or "--help" (full usage "$ myapp test -h" or "$ myapp test --help")
+ // > A version flag (automatically generated by clap
+ // = Uses "-V" or "--version" (full usage "$ myapp test -V" or "$ myapp test --version")
+ // - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own)
+ // + Used by "$ myapp help" (same functionality as "-h" or "--help")
+ let matches = App::new("MyApp")
+ .version("1.0")
+ .author("Kevin K. <kbknapp@gmail.com>")
+ .about("Does awesome things")
+ .arg(Arg::with_name("config")
+ .short("c")
+ .long("config")
+ .value_name("FILE")
+ .help("Sets a custom config file")
+ .takes_value(true))
+ .arg(Arg::with_name("output")
+ .help("Sets an optional output file")
+ .index(1))
+ .arg(Arg::with_name("debug")
+ .short("d")
+ .multiple(true)
+ .help("Turn debugging information on"))
+ .subcommand(SubCommand::with_name("test")
+ .about("does testing things")
+ .arg(Arg::with_name("list")
+ .short("l")
+ .help("lists test values")))
+ .get_matches();
+
+ // You can check the value provided by positional arguments, or option arguments
+ if let Some(o) = matches.value_of("output") {
+ println!("Value for output: {}", o);
+ }
+
+ if let Some(c) = matches.value_of("config") {
+ println!("Value for config: {}", c);
+ }
+
+ // You can see how many times a particular flag or argument occurred
+ // Note, only flags can have multiple occurrences
+ match matches.occurrences_of("debug") {
+ 0 => println!("Debug mode is off"),
+ 1 => println!("Debug mode is kind of on"),
+ 2 => println!("Debug mode is on"),
+ 3 | _ => println!("Don't be crazy"),
+ }
+
+ // You can check for the existence of subcommands, and if found use their
+ // matches just as you would the top level app
+ if let Some(matches) = matches.subcommand_matches("test") {
+ // "$ myapp test" was run
+ if matches.is_present("list") {
+ // "$ myapp test -l" was run
+ println!("Printing testing lists...");
+ } else {
+ println!("Not printing testing lists...");
+ }
+ }
+
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/01c_quick_example.rs b/clap/examples/01c_quick_example.rs
new file mode 100644
index 0000000..071bdc0
--- /dev/null
+++ b/clap/examples/01c_quick_example.rs
@@ -0,0 +1,75 @@
+#[macro_use]
+extern crate clap;
+
+fn main() {
+ // This example shows how to create an application with several arguments using macro builder.
+ // It combines the simplicity of the from_usage methods and the performance of the Builder Pattern.
+ //
+ // The example below is functionally identical to the one in 01a_quick_example.rs and 01b_quick_example.rs
+ //
+ // Create an application with 5 possible arguments (2 auto generated) and 2 subcommands (1 auto generated)
+ // - A config file
+ // + Uses "-c filename" or "--config filename"
+ // - An output file
+ // + A positional argument (i.e. "$ myapp output_filename")
+ // - A debug flag
+ // + Uses "-d" or "--debug"
+ // + Allows multiple occurrences of such as "-dd" (for vary levels of debugging, as an example)
+ // - A help flag (automatically generated by clap)
+ // + Uses "-h" or "--help" (Only autogenerated if you do NOT specify your own "-h" or "--help")
+ // - A version flag (automatically generated by clap)
+ // + Uses "-V" or "--version" (Only autogenerated if you do NOT specify your own "-V" or "--version")
+ // - A subcommand "test" (subcommands behave like their own apps, with their own arguments
+ // + Used by "$ myapp test" with the following arguments
+ // > A list flag
+ // = Uses "-l" (usage is "$ myapp test -l"
+ // > A help flag (automatically generated by clap
+ // = Uses "-h" or "--help" (full usage "$ myapp test -h" or "$ myapp test --help")
+ // > A version flag (automatically generated by clap
+ // = Uses "-V" or "--version" (full usage "$ myapp test -V" or "$ myapp test --version")
+ // - A subcommand "help" (automatically generated by clap because we specified a subcommand of our own)
+ // + Used by "$ myapp help" (same functionality as "-h" or "--help")
+ let matches = clap_app!(myapp =>
+ (version: "1.0")
+ (author: "Kevin K. <kbknapp@gmail.com>")
+ (about: "Does awesome things")
+ (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
+ (@arg INPUT: +required "Sets the input file to use")
+ (@arg debug: -d ... "Sets the level of debugging information")
+ (@subcommand test =>
+ (about: "controls testing features")
+ (version: "1.3")
+ (author: "Someone E. <someone_else@other.com>")
+ (@arg verbose: -v --verbose "Print test information verbosely")
+ )
+ ).get_matches();
+
+ // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
+ // required we could have used an 'if let' to conditionally get the value)
+ println!("Using input file: {}", matches.value_of("INPUT").unwrap());
+
+ // Gets a value for config if supplied by user, or defaults to "default.conf"
+ let config = matches.value_of("CONFIG").unwrap_or("default.conf");
+ println!("Value for config: {}", config);
+
+ // Vary the output based on how many times the user used the "debug" flag
+ // (i.e. 'myapp -d -d -d' or 'myapp -ddd' vs 'myapp -d'
+ match matches.occurrences_of("debug") {
+ 0 => println!("Debug mode is off"),
+ 1 => println!("Debug mode is kind of on"),
+ 2 => println!("Debug mode is on"),
+ 3 | _ => println!("Don't be crazy"),
+ }
+
+ // You can information about subcommands by requesting their matches by name
+ // (as below), requesting just the name used, or both at the same time
+ if let Some(matches) = matches.subcommand_matches("test") {
+ if matches.is_present("verbose") {
+ println!("Printing verbosely...");
+ } else {
+ println!("Printing normally...");
+ }
+ }
+
+ // more program logic goes here...
+}
diff --git a/clap/examples/02_apps.rs b/clap/examples/02_apps.rs
new file mode 100644
index 0000000..8e45640
--- /dev/null
+++ b/clap/examples/02_apps.rs
@@ -0,0 +1,30 @@
+extern crate clap;
+
+use clap::App;
+
+fn main() {
+ // Apps describe the top level application
+ //
+ // You create an App and set various options on that App using the "builder pattern"
+ //
+ // The options (version(), author(), about()) aren't mandatory, but recommended. There is
+ // another option, usage(), which is an exception to the rule. This should only be used when
+ // the default usage string automatically generated by clap doesn't suffice.
+ //
+ // You also set all the valid arguments your App should accept via the arg(), args(), arg_from_usage()
+ // and args_from_usage() (as well as subcommands via the subcommand() and subcommands() methods) which
+ // will be covered later.
+ //
+ // Once all options have been set, call one of the .get_matches* family of methods in order to
+ // start the parsing and find all valid command line arguments that supplied by the user at
+ // runtime. The name given to new() will be displayed when the version or help flags are used.
+ App::new("MyApp")
+ .version("1.0")
+ .author("Kevin K. <kbknapp@gmail.com>")
+ .about("Does awesome things")
+ .get_matches();
+
+ // This example doesn't do much, but it *does* give automatic -h, --help, -V, and --version functionality ;)
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/03_args.rs b/clap/examples/03_args.rs
new file mode 100644
index 0000000..c62d576
--- /dev/null
+++ b/clap/examples/03_args.rs
@@ -0,0 +1,84 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+ // Args describe a possible valid argument which may be supplied by the user at runtime. There
+ // are three different types of arguments (flags, options, and positional) as well as a fourth
+ // special type of argument, called SubCommands (which will be discussed separately).
+ //
+ // Args are described in the same manner as Apps using the "builder pattern" with multiple
+ // methods describing various settings for the individual arguments. Or by supplying a "usage"
+ // string. Both methods have their pros and cons.
+ //
+ // Arguments can be added to applications in two manners, one at a time with the arg(), and
+ // arg_from_usage() method, or multiple arguments at once via a Vec<Arg> inside the args() method,
+ // or a single &str describing multiple Args (one per line) supplied to args_from_usage().
+ //
+ // There are various options which can be set for a given argument, some apply to any of the
+ // three types of arguments, some only apply one or two of the types. *NOTE* if you set
+ // incompatible options on a single argument, clap will panic! at runtime. This is by design,
+ // so that you know right away an error was made by the developer, not the end user.
+ //
+ // # Help and Version
+ // clap automatically generates a help and version flag for you, unless you specify your
+ // own. By default help uses "-h" and "--help", and version uses "-V" and "--version". You can
+ // safely override "-V" and "-h" to your own arguments, and "--help" and "--version" will still
+ // be automatically generated for you.
+ let matches = App::new("MyApp")
+ // All application settings go here...
+
+ // A simple "Flag" argument example (i.e. "-d") using the builder pattern
+ .arg(Arg::with_name("debug")
+ .help("turn on debugging information")
+ .short("d"))
+
+ // Two arguments, one "Option" argument (i.e. one that takes a value) such
+ // as "-c some", and one positional argument (i.e. "myapp some_file")
+ .args(&[
+ Arg::with_name("config")
+ .help("sets the config file to use")
+ .takes_value(true)
+ .short("c")
+ .long("config"),
+ Arg::with_name("input")
+ .help("the input file to use")
+ .index(1)
+ .required(true)
+ ])
+
+ // *Note* the following two examples are convenience methods, if you wish
+ // to still get the full configurability of Arg::with_name() and the readability
+ // of arg_from_usage(), you can instantiate a new Arg with Arg::from_usage() and
+ // still be able to set all the additional properties, just like Arg::with_name()
+ //
+ //
+ // One "Flag" using a usage string
+ .arg_from_usage("--license 'display the license file'")
+
+ // Two args, one "Positional", and one "Option" using a usage string
+ .args_from_usage("[output] 'Supply an output file to use'
+ -i, --int=[IFACE] 'Set an interface to use'")
+ .get_matches();
+
+ // Here are some examples of using the arguments defined above. Keep in mind that this is only
+ // an example, and may be somewhat contrived
+ //
+ // First we check if debugging should be on or not
+ println!("Debugging mode is: {}", if matches.is_present("debug") { "ON" } else { "OFF" });
+
+ // Next we print the config file we're using, if any was defined with either -c <file> or
+ // --config <file>
+ if let Some(config) = matches.value_of("config") {
+ println!("A config file was passed in: {}", config);
+ }
+
+ // Let's print the <INPUT> file the user passed in. We can use .unwrap() here becase the arg is
+ // required, and parsing would have failed if the user forgot it
+ println!("Using input file: {}", matches.value_of("input").unwrap());
+
+ // We could continue checking for and using arguments in this manner, such as "license",
+ // "output", and "interface". Keep in mind that "output" and "interface" are optional, so you
+ // shouldn't call .unwrap(). Instead, prefer using an 'if let' expression as we did with
+ // "config"
+}
diff --git a/clap/examples/04_using_matches.rs b/clap/examples/04_using_matches.rs
new file mode 100644
index 0000000..a0a986f
--- /dev/null
+++ b/clap/examples/04_using_matches.rs
@@ -0,0 +1,54 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+
+ // Once all App settings (including all arguments) have been set, you call get_matches() which
+ // parses the string provided by the user, and returns all the valid matches to the ones you
+ // specified.
+ //
+ // You can then query the matches struct to get information about how the user ran the program
+ // at startup.
+ //
+ // For this example, let's assume you created an App which accepts three arguments (plus two
+ // generated by clap), a flag to display debugging information triggered with "-d" or
+ // "--debug" as well as an option argument which specifies a custom configuration file to use
+ // triggered with "-c file" or "--config file" or "--config=file" and finally a positional
+ // argument which is the input file we want to work with, this will be the only required
+ // argument.
+ let matches = App::new("MyApp")
+ .about("Parses an input file to do awesome things")
+ .version("1.0")
+ .author("Kevin K. <kbknapp@gmail.com>")
+ .arg(Arg::with_name("debug")
+ .help("turn on debugging information")
+ .short("d")
+ .long("debug"))
+ .arg(Arg::with_name("config")
+ .help("sets the config file to use")
+ .short("c")
+ .long("config"))
+ .arg(Arg::with_name("input")
+ .help("the input file to use")
+ .index(1)
+ .required(true))
+ .get_matches();
+
+ // We can find out whether or not debugging was turned on
+ if matches.is_present("debug") {
+ println!("Debugging is turned on");
+ }
+
+ // If we wanted to do some custom initialization based off some configuration file
+ // provided by the user, we could get the file (A string of the file)
+ if let Some(file) = matches.value_of("config") {
+ println!("Using config file: {}", file);
+ }
+
+ // Because "input" is required we can safely call unwrap() because had the user NOT
+ // specified a value, clap would have explained the error the user, and exited.
+ println!("Doing real work with file: {}", matches.value_of("input").unwrap() );
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/05_flag_args.rs b/clap/examples/05_flag_args.rs
new file mode 100644
index 0000000..a6b8945
--- /dev/null
+++ b/clap/examples/05_flag_args.rs
@@ -0,0 +1,56 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+
+ // Of the three argument types, flags are the most simple. Flags are simple switches which can
+ // be either "on" or "off"
+ //
+ // clap also supports multiple occurrences of flags, the common example is "verbosity" where a
+ // user could want a little information with "-v" or tons of information with "-v -v" or "-vv"
+ let matches = App::new("MyApp")
+ // Regular App configuration goes here...
+
+ // We'll add a flag that represents an awesome meter...
+ //
+ // I'll explain each possible setting that "flags" accept. Keep in mind
+ // that you DO NOT need to set each of these for every flag, only the ones
+ // you want for your individual case.
+ .arg(Arg::with_name("awesome")
+ .help("turns up the awesome") // Displayed when showing help info
+ .short("a") // Trigger this arg with "-a"
+ .long("awesome") // Trigger this arg with "--awesome"
+ .multiple(true) // This flag should allow multiple
+ // occurrences such as "-aaa" or "-a -a"
+ .requires("config") // Says, "If the user uses -a, they MUST
+ // also use this other 'config' arg too"
+ // Can also specify a list using
+ // requires_all(Vec<&str>)
+ .conflicts_with("output") // Opposite of requires(), says "if the
+ // user uses -a, they CANNOT use 'output'"
+ // also has a conflicts_with_all(Vec<&str>)
+ )
+ // NOTE: In order to compile this example, comment out requires() and
+ // conflicts_with() because we have not defined an "output" or "config"
+ // argument.
+ .get_matches();
+
+ // We can find out whether or not awesome was used
+ if matches.is_present("awesome") {
+ println!("Awesomeness is turned on");
+ }
+
+ // If we set the multiple() option of a flag we can check how many times the user specified
+ //
+ // Note: if we did not specify the multiple() option, and the user used "awesome" we would get
+ // a 1 (no matter how many times they actually used it), or a 0 if they didn't use it at all
+ match matches.occurrences_of("awesome") {
+ 0 => println!("Nothing is awesome"),
+ 1 => println!("Some things are awesome"),
+ 2 => println!("Lots of things are awesome"),
+ 3 | _ => println!("EVERYTHING is awesome!"),
+ }
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/06_positional_args.rs b/clap/examples/06_positional_args.rs
new file mode 100644
index 0000000..1f29612
--- /dev/null
+++ b/clap/examples/06_positional_args.rs
@@ -0,0 +1,56 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+
+ // Positional arguments are those values after the program name which are not preceded by any
+ // identifier (such as "myapp some_file"). Positionals support many of the same options as
+ // flags, as well as a few additional ones.
+ let matches = App::new("MyApp")
+ // Regular App configuration goes here...
+
+ // We'll add two positional arguments, a input file, and a config file.
+ //
+ // I'll explain each possible setting that "positionals" accept. Keep in
+ // mind that you DO NOT need to set each of these for every flag, only the
+ // ones that apply to your individual case.
+ .arg(Arg::with_name("input")
+ .help("the input file to use") // Displayed when showing help info
+ .index(1) // Set the order in which the user must
+ // specify this argument (Starts at 1)
+ .requires("config") // Says, "If the user uses "input", they MUST
+ // also use this other 'config' arg too"
+ // Can also specify a list using
+ // requires_all(Vec<&str>)
+ .conflicts_with("output") // Opposite of requires(), says "if the
+ // user uses -a, they CANNOT use 'output'"
+ // also has a conflicts_with_all(Vec<&str>)
+ .required(true) // By default this argument MUST be present
+ // NOTE: mutual exclusions take precedence over
+ // required arguments
+ )
+ .arg(Arg::with_name("config")
+ .help("the config file to use")
+ .index(2)) // Note, we do not need to specify required(true)
+ // if we don't want to, because "input" already
+ // requires "config"
+ // Note, we also do not need to specify requires("input")
+ // because requires lists are automatically two-way
+
+ // NOTE: In order to compile this example, comment out conflicts_with()
+ // because we have not defined an "output" argument.
+ .get_matches();
+
+ // We can find out whether or not "input" or "config" were used
+ if matches.is_present("input") {
+ println!("An input file was specified");
+ }
+
+ // We can also get the values for those arguments
+ if let Some(in_file) = matches.value_of("input") {
+ // It's safe to call unwrap() because of the required options we set above
+ println!("Doing work with {} and {}", in_file, matches.value_of("config").unwrap());
+ }
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/07_option_args.rs b/clap/examples/07_option_args.rs
new file mode 100644
index 0000000..85ff0e5
--- /dev/null
+++ b/clap/examples/07_option_args.rs
@@ -0,0 +1,71 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+
+ // Option arguments are those that take an additional value, such as "-c value". In clap they
+ // support three types of specification, those with short() as "-o some", or those with long()
+ // as "--option value" or "--option=value"
+ //
+ // Options also support a multiple setting, which is discussed in the example below.
+ let matches = App::new("MyApp")
+ // Regular App configuration goes here...
+
+ // Assume we have an application that accepts an input file via the "-i file"
+ // or the "--input file" (as well as "--input=file").
+ // Below every setting supported by option arguments is discussed.
+ // NOTE: You DO NOT need to specify each setting, only those which apply
+ // to your particular case.
+ .arg(Arg::with_name("input")
+ .help("the input file to use") // Displayed when showing help info
+ .takes_value(true) // MUST be set to true in order to be an "option" argument
+ .short("i") // This argument is triggered with "-i"
+ .long("input") // This argument is triggered with "--input"
+ .multiple(true) // Set to true if you wish to allow multiple occurrences
+ // such as "-i file -i other_file -i third_file"
+ .required(true) // By default this argument MUST be present
+ // NOTE: mutual exclusions take precedence over
+ // required arguments
+ .requires("config") // Says, "If the user uses "input", they MUST
+ // also use this other 'config' arg too"
+ // Can also specify a list using
+ // requires_all(Vec<&str>)
+ .conflicts_with("output") // Opposite of requires(), says "if the
+ // user uses -a, they CANNOT use 'output'"
+ // also has a conflicts_with_all(Vec<&str>)
+ )
+ // NOTE: In order to compile this example, comment out conflicts_with()
+ // and requires() because we have not defined an "output" or "config"
+ // argument.
+ .get_matches();
+
+ // We can find out whether or not "input" was used
+ if matches.is_present("input") {
+ println!("An input file was specified");
+ }
+
+ // We can also get the value for "input"
+ //
+ // NOTE: If we specified multiple(), this will only return the _FIRST_
+ // occurrence
+ if let Some(in_file) = matches.value_of("input") {
+ println!("An input file: {}", in_file);
+ }
+
+ // If we specified the multiple() setting we can get all the values
+ if let Some(in_v) = matches.values_of("input") {
+ for in_file in in_v {
+ println!("An input file: {}", in_file);
+ }
+ }
+
+ // We can see how many times the option was used with the occurrences_of() method
+ //
+ // NOTE: Just like with flags, if we did not specify the multiple() setting this will only
+ // return 1 no matter how many times the argument was used (unless it wasn't used at all, in
+ // in which case 0 is returned)
+ println!("The \"input\" argument was used {} times", matches.occurrences_of("input"));
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/08_subcommands.rs b/clap/examples/08_subcommands.rs
new file mode 100644
index 0000000..73bd098
--- /dev/null
+++ b/clap/examples/08_subcommands.rs
@@ -0,0 +1,57 @@
+extern crate clap;
+
+use clap::{App, Arg, SubCommand};
+
+fn main() {
+
+ // SubCommands function exactly like sub-Apps, because that's exactly what they are. Each
+ // instance of a SubCommand can have it's own version, author(s), Args, and even it's own
+ // subcommands.
+ //
+ // # Help and Version
+ // Just like Apps, each subcommand will get it's own "help" and "version" flags automatically
+ // generated. Also, like Apps, you can override "-V" or "-h" safely and still get "--help" and
+ // "--version" auto generated.
+ //
+ // NOTE: If you specify a subcommand for your App, clap will also autogenerate a "help"
+ // subcommand along with "-h" and "--help" (applies to sub-subcommands as well).
+ //
+ // Just like arg() and args(), subcommands can be specified one at a time via subcommand() or
+ // multiple ones at once with a Vec<SubCommand> provided to subcommands().
+ let matches = App::new("MyApp")
+ // Normal App and Arg configuration goes here...
+
+ // In the following example assume we wanted an application which
+ // supported an "add" subcommand, this "add" subcommand also took
+ // one positional argument of a file to add:
+ .subcommand(SubCommand::with_name("add") // The name we call argument with
+ .about("Adds files to myapp") // The message displayed in "myapp -h"
+ // or "myapp help"
+ .version("0.1") // Subcommands can have independent version
+ .author("Kevin K.") // And authors
+ .arg(Arg::with_name("input") // And their own arguments
+ .help("the file to add")
+ .index(1)
+ .required(true)))
+ .get_matches();
+
+ // You can check if a subcommand was used like normal
+ if matches.is_present("add") {
+ println!("'myapp add' was run.");
+ }
+
+ // You can get the independent subcommand matches (which function exactly like App matches)
+ if let Some(matches) = matches.subcommand_matches("add") {
+ // Safe to use unwrap() because of the required() option
+ println!("Adding file: {}", matches.value_of("input").unwrap());
+ }
+
+ // You can also match on a subcommand's name
+ match matches.subcommand_name() {
+ Some("add") => println!("'myapp add' was used"),
+ None => println!("No subcommand was used"),
+ _ => println!("Some other subcommand was used"),
+ }
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/09_auto_version.rs b/clap/examples/09_auto_version.rs
new file mode 100644
index 0000000..dfd221f
--- /dev/null
+++ b/clap/examples/09_auto_version.rs
@@ -0,0 +1,29 @@
+#[macro_use]
+extern crate clap;
+
+use clap::App;
+
+fn main() {
+ // You can have clap pull the application version directly from your Cargo.toml starting with
+ // clap v0.4.14 on crates.io (or master#a81f915 on github). Using Rust's env! macro like this:
+ //
+ // let version = format!("{}.{}.{}{}",
+ // env!("CARGO_PKG_VERSION_MAJOR"),
+ // env!("CARGO_PKG_VERSION_MINOR"),
+ // env!("CARGO_PKG_VERSION_PATCH"),
+ // option_env!("CARGO_PKG_VERSION_PRE").unwrap_or(""));
+ //
+ // Starting from v0.6.6 on crates.io you can also use the crate_version!() macro instead of
+ // manually using the env!() macros. Under the hood, the macro uses this exact method to get
+ // the version.
+ //
+ // Thanks to https://github.com/jhelwig for pointing this out
+ App::new("myapp")
+ .about("does awesome things")
+ // use crate_version! to pull the version number
+ .version(crate_version!())
+ .get_matches();
+
+ // running this app with the -V or --version will display whatever version is in your
+ // Cargo.toml, the default being: myapp 0.0.1
+}
diff --git a/clap/examples/10_default_values.rs b/clap/examples/10_default_values.rs
new file mode 100644
index 0000000..ca50981
--- /dev/null
+++ b/clap/examples/10_default_values.rs
@@ -0,0 +1,40 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+ // There are two ways in which to get a default value, one is to use claps Arg::default_value
+ // method, and the other is to use Rust's built in Option::unwrap_or method.
+ //
+ // I'll demo both here.
+ //
+ // First, we'll use clap's Arg::default_value with an "INPUT" file.
+ let matches = App::new("myapp").about("does awesome things")
+ .arg(Arg::with_name("INPUT")
+ .help("The input file to use") // Note, we don't need to specify
+ // anything like, "Defaults to..."
+ // because clap will automatically
+ // generate that for us, and place
+ // it in the help text
+ .default_value("input.txt")
+ .index(1))
+
+ // Next we'll use the Option::unwrap_or method on this "CONFIG" option
+ .arg(Arg::with_name("CONFIG")
+ // Note that we have to manually include some verbiage to the user
+ // telling them what the default will be.
+ .help("The config file to use (default is \"config.json\")")
+ .short("c")
+ .takes_value(true))
+ .get_matches();
+
+ // It's safe to call unwrap because the value with either be what the user input at runtime
+ // or "input.txt"
+ let input = matches.value_of("INPUT").unwrap();
+
+ // Using Option::unwrap_or we get the same affect, but without the added help text injection
+ let config_file = matches.value_of("CONFIG").unwrap_or("config.json");
+
+ println!("The input file is: {}", input);
+ println!("The config file is: {}", config_file);
+}
diff --git a/clap/examples/11_only_specific_values.rs b/clap/examples/11_only_specific_values.rs
new file mode 100644
index 0000000..3445218
--- /dev/null
+++ b/clap/examples/11_only_specific_values.rs
@@ -0,0 +1,33 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+ // If you have arguments of specific values you want to test for, you can use the
+ // .possible_values() method of Arg
+ //
+ // This allows you specify the valid values for that argument. If the user does not use one of
+ // those specific values, they will receive a graceful exit with error message informing them
+ // of the mistake, and what the possible valid values are
+ //
+ // For this example, assume you want one positional argument of either "fast" or "slow"
+ // i.e. the only possible ways to run the program are "myprog fast" or "myprog slow"
+ let matches = App::new("myapp").about("does awesome things")
+ .arg(Arg::with_name("MODE")
+ .help("What mode to run the program in")
+ .index(1)
+ .possible_values(&["fast", "slow"])
+ .required(true))
+ .get_matches();
+
+ // Note, it's safe to call unwrap() because the arg is required
+ match matches.value_of("MODE").unwrap() {
+ "fast" => {
+ // Do fast things...
+ },
+ "slow" => {
+ // Do slow things...
+ },
+ _ => unreachable!()
+ }
+}
diff --git a/clap/examples/12_typed_values.rs b/clap/examples/12_typed_values.rs
new file mode 100644
index 0000000..3d03e4f
--- /dev/null
+++ b/clap/examples/12_typed_values.rs
@@ -0,0 +1,50 @@
+#[macro_use]
+extern crate clap;
+
+use clap::App;
+
+fn main() {
+ // You can use some convenience macros provided by clap to get typed values, so long as the
+ // type you specify implements std::str::FromStr
+ //
+ // This works for both single, and multiple values (multiple values returns a Vec<T>)
+ //
+ // There are also two ways in which to get types, those where failures cause the program to exit
+ // with an error and usage string, and those which return a Result<T,String> or Result<Vec<T>,String>
+ // respectively. Both methods support single and multiple values.
+ //
+ // The macro which returns a Result allows you decide what to do upon a failure, exit, provide a
+ // default value, etc. You have control. But it also means you have to write the code or boiler plate
+ // to handle those instances.
+ //
+ // That is why the second method exists, so you can simply get a T or Vec<T> back, or be sure the
+ // program will exit gracefully. The catch is, the second method should *only* be used on required
+ // arguments, because if the argument isn't found, it exits. Just FYI ;)
+ //
+ // The following example shows both methods.
+ //
+ // **NOTE:** to use the macros, you must include #[macro_use] just above the 'extern crate clap;'
+ // declaration in your crate root.
+ let matches = App::new("myapp")
+ // Create two arguments, a required positional which accepts multiple values
+ // and an optional '-l value'
+ .args_from_usage(
+ "<seq>... 'A sequence of whole positive numbers, i.e. 20 25 30'
+ -l [len] 'A length to use, defaults to 10 when omitted'")
+ .get_matches();
+
+ // Here we get a value of type u32 from our optional -l argument.
+ // If the value provided to len fails to parse, we default to 10
+ //
+ // Using other methods such as unwrap_or_else(|e| println!("{}",e))
+ // are possible too.
+ let len = value_t!(matches, "len", u32).unwrap_or(10);
+
+ println!("len ({}) + 2 = {}", len, len + 2);
+
+ // This code loops through all the values provided to "seq" and adds 2
+ // If seq fails to parse, the program exits, you don't have an option
+ for v in values_t!(matches, "seq", u32).unwrap_or_else(|e| e.exit()) {
+ println!("Sequence part {} + 2: {}", v, v + 2);
+ }
+}
diff --git a/clap/examples/13a_enum_values_automatic.rs b/clap/examples/13a_enum_values_automatic.rs
new file mode 100644
index 0000000..1abe5cb
--- /dev/null
+++ b/clap/examples/13a_enum_values_automatic.rs
@@ -0,0 +1,68 @@
+// You can use clap's value_t! macro with a custom enum by implementing the std::str::FromStr
+// trait which is very straight forward. There are three ways to do this, for simple enums
+// meaning those that don't require 'pub' or any '#[derive()]' directives you can use clap's
+// simple_enum! macro. For those that require 'pub' or any '#[derive()]'s you can use clap's
+// arg_enum! macro. The third way is to implement std::str::FromStr manually.
+//
+// In most circumstances using either simple_enum! or arg_enum! is fine.
+//
+// In the following example we will create two enums using macros, assign a positional argument
+// that accepts only one of those values, and use clap to parse the argument.
+
+// Add clap like normal
+#[macro_use]
+extern crate clap;
+
+use clap::{App, Arg};
+
+// Using arg_enum! is more like traditional enum declarations
+//
+// **NOTE:** Only bare variants are supported
+arg_enum!{
+ #[derive(Debug)]
+ pub enum Oof {
+ Rab,
+ Zab,
+ Xuq
+ }
+}
+
+arg_enum!{
+ #[derive(Debug)]
+ enum Foo {
+ Bar,
+ Baz,
+ Qux
+ }
+}
+
+fn main() {
+ // Create the application like normal
+ let enum_vals = ["fast", "slow"];
+ let m = App::new("myapp")
+ // Use a single positional argument that is required
+ .arg(Arg::from_usage("<foo> 'The Foo to use'")
+ .possible_values(&Foo::variants()))
+ .arg(Arg::from_usage("<speed> 'The speed to use'")
+ // You can define a list of possible values if you want the values to be
+ // displayed in the help information. Whether you use possible_values() or
+ // not, the valid values will ALWAYS be displayed on a failed parse.
+ .possible_values(&enum_vals))
+ // For the second positional, lets not use possible_values() just to show the difference
+ .arg_from_usage("<oof> 'The Oof to use'")
+ .get_matches();
+
+ let t = value_t!(m.value_of("foo"), Foo).unwrap_or_else(|e| e.exit());
+ let t2 = value_t!(m.value_of("oof"), Oof).unwrap_or_else(|e| e.exit());
+
+
+ // Now we can use our enum like normal.
+ match t {
+ Foo::Bar => println!("Found a Bar"),
+ Foo::Baz => println!("Found a Baz"),
+ Foo::Qux => println!("Found a Qux")
+ }
+
+ // Since our Oof derives Debug, we can do this:
+ println!("Oof: {:?}", t2);
+}
diff --git a/clap/examples/13b_enum_values_manual.rs b/clap/examples/13b_enum_values_manual.rs
new file mode 100644
index 0000000..81ffe5e
--- /dev/null
+++ b/clap/examples/13b_enum_values_manual.rs
@@ -0,0 +1,54 @@
+// In the following example we will create an enum with 4 values, assign a positional argument
+// that accepts only one of those values, and use clap to parse the argument.
+//
+// Start with bringing the trait into scope.
+use std::str::FromStr;
+
+// Add clap like normal
+#[macro_use]
+extern crate clap;
+
+use clap::{App, Arg};
+
+// Define your enum
+enum Vals {
+ Foo,
+ Bar,
+ Baz,
+ Qux
+}
+
+// Implement the trait
+impl FromStr for Vals {
+ type Err = &'static str;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match s {
+ "Foo" => Ok(Vals::Foo),
+ "Bar" => Ok(Vals::Bar),
+ "Baz" => Ok(Vals::Baz),
+ "Qux" => Ok(Vals::Qux),
+ _ => Err("no match")
+ }
+ }
+}
+
+fn main() {
+ // Create the application like normal
+ let m = App::new("myapp")
+ // Use a single positional argument that is required
+ .arg(Arg::from_usage("<type> 'The type to use'")
+ // Define the list of possible values
+ .possible_values(&["Foo", "Bar", "Baz", "Qux"]))
+ .get_matches();
+
+ let t = value_t!(m, "type", Vals).unwrap_or_else(|e| e.exit());
+
+ // Now we can use our enum like normal.
+ match t {
+ Vals::Foo => println!("Found a Foo"),
+ Vals::Bar => println!("Found a Bar"),
+ Vals::Baz => println!("Found a Baz"),
+ Vals::Qux => println!("Found a Qux")
+ }
+}
diff --git a/clap/examples/14_groups.rs b/clap/examples/14_groups.rs
new file mode 100644
index 0000000..e160464
--- /dev/null
+++ b/clap/examples/14_groups.rs
@@ -0,0 +1,87 @@
+/// `ArgGroup`s are a family of related arguments and way for you to say, "Any of these arguments".
+/// By placing arguments in a logical group, you can make easier requirement and exclusion rules
+/// instead of having to list each individually, or when you want a rule to apply "any but not all"
+/// arguments.
+///
+/// For instance, you can make an entire `ArgGroup` required, this means that one (and *only* one)
+/// argument from that group must be present. Using more than one argument from an `ArgGroup` causes
+/// a failure (graceful exit).
+///
+/// You can also do things such as name an `ArgGroup` as a confliction or requirement, meaning any
+/// of the arguments that belong to that group will cause a failure if present, or must present
+/// respectively.
+///
+/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
+/// present out of a given set. Imagine that you had multiple arguments, and you want one of them to
+/// be required, but making all of them required isn't feasible because perhaps they conflict with
+/// each other. For example, lets say that you were building an application where one could set a
+/// given version number by supplying a string with an option argument, i.e. `--set-ver v1.2.3`, you
+/// also wanted to support automatically using a previous version number and simply incrementing one
+/// of the three numbers. So you create three flags `--major`, `--minor`, and `--patch`. All of
+/// these arguments shouldn't be used at one time but you want to specify that *at least one* of
+/// them is used. For this, you can create a group.
+
+extern crate clap;
+
+use clap::{App, Arg, ArgGroup};
+
+fn main() {
+ // Create application like normal
+ let matches = App::new("myapp")
+ // Add the version arguments
+ .args_from_usage("--set-ver [ver] 'set version manually'
+ --major 'auto inc major'
+ --minor 'auto inc minor'
+ --patch 'auto inc patch'")
+ // Create a group, make it required, and add the above arguments
+ .group(ArgGroup::with_name("vers")
+ .required(true)
+ .args(&["ver", "major", "minor", "patch"]))
+ // Arguments can also be added to a group individually, these two arguments
+ // are part of the "input" group which is not required
+ .arg(Arg::from_usage("[INPUT_FILE] 'some regular input'")
+ .group("input"))
+ .arg(Arg::from_usage("--spec-in [SPEC_IN] 'some special input argument'")
+ .group("input"))
+ // Now let's assume we have a -c [config] argument which requires one of
+ // (but **not** both) the "input" arguments
+ .arg(Arg::with_name("config")
+ .short("c")
+ .takes_value(true)
+ .requires("input"))
+ .get_matches();
+
+ // Let's assume the old version 1.2.3
+ let mut major = 1;
+ let mut minor = 2;
+ let mut patch = 3;
+
+ // See if --set-ver was used to set the version manually
+ let version = if let Some(ver) = matches.value_of("ver") {
+ format!("{}", ver)
+ } else {
+ // Increment the one requested (in a real program, we'd reset the lower numbers)
+ let (maj, min, pat) = (matches.is_present("major"),
+ matches.is_present("minor"),
+ matches.is_present("patch"));
+ match (maj, min, pat) {
+ (true, _, _) => major += 1,
+ (_, true, _) => minor += 1,
+ (_, _, true) => patch += 1,
+ _ => unreachable!(),
+ };
+ format!("{}.{}.{}", major, minor, patch)
+ };
+
+ println!("Version: {}", version);
+
+ // Check for usage of -c
+ if matches.is_present("config") {
+ let input = matches.value_of("INPUT_FILE").unwrap_or(matches.value_of("SPEC_IN").unwrap());
+ println!("Doing work using input {} and config {}",
+ input,
+ matches.value_of("config").unwrap());
+ }
+
+
+}
diff --git a/clap/examples/15_custom_validator.rs b/clap/examples/15_custom_validator.rs
new file mode 100644
index 0000000..a5c0d42
--- /dev/null
+++ b/clap/examples/15_custom_validator.rs
@@ -0,0 +1,37 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+fn main() {
+ // You can define a function (or a closure) to use as a validator to argument values. The
+ // function must accept a String and return Result<(), String> where Err(String) is the message
+ // displayed to the user.
+
+ let matches = App::new("myapp")
+ // Application logic goes here...
+ .arg(Arg::with_name("input")
+ .help("the input file to use")
+ .index(1)
+ .required(true)
+ // You can pass in a closure, or a function
+ .validator(is_png))
+ .get_matches();
+
+ // Here we can call .unwrap() because the argument is required.
+ println!("The .PNG file is: {}", matches.value_of("input").unwrap());
+}
+
+fn is_png(val: String) -> Result<(), String> {
+ // val is the argument value passed in by the user
+ // val has type of String.
+ if val.ends_with(".png") {
+ Ok(())
+ } else {
+ // clap automatically adds "error: " to the beginning
+ // of the message.
+ Err(String::from("the file format must be png."))
+ }
+ // Of course, you can do more complicated validation as
+ // well, but for the simplicity, this example only checks
+ // if the value passed in ends with ".png" or not.
+}
diff --git a/clap/examples/16_app_settings.rs b/clap/examples/16_app_settings.rs
new file mode 100644
index 0000000..ab1d185
--- /dev/null
+++ b/clap/examples/16_app_settings.rs
@@ -0,0 +1,41 @@
+extern crate clap;
+
+use clap::{App, AppSettings, SubCommand};
+
+fn main() {
+ // You can use AppSettings to change the application level behavior of clap. .setting() function
+ // of App struct takes AppSettings enum as argument. There is also .settings() function which
+ // takes slice of AppSettings enum. You can learn more about AppSettings in the documentation,
+ // which also has examples on each setting.
+ //
+ // This example will only show usage of one AppSettings setting. See documentation for more
+ // information.
+
+ let matches = App::new("myapp")
+ .setting(AppSettings::SubcommandsNegateReqs)
+ // Negates requirement of parent command.
+
+ .arg_from_usage("<input> 'input file to use'")
+ // Required positional argument called input. This
+ // will be only required if subcommand is not present.
+
+ .subcommand(SubCommand::with_name("test")
+ .about("does some testing"))
+ // if program is invoked with subcommand, you do not
+ // need to specify the <input> argument anymore due to
+ // the AppSettings::SubcommandsNegateReqs setting.
+
+ .get_matches();
+
+ // Calling unwrap() on "input" would not be advised here, because although it's required,
+ // if the user uses a subcommand, those requirements are no longer required. Hence, we should
+ // use some sort of 'if let' construct
+ if let Some(inp) = matches.value_of("input") {
+ println!("The input file is: {}", inp);
+ }
+
+ match matches.subcommand() {
+ ("test", _) => println!("The 'test' subcommand was used"),
+ _ => unreachable!()
+ }
+}
diff --git a/clap/examples/17_yaml.rs b/clap/examples/17_yaml.rs
new file mode 100644
index 0000000..3353d73
--- /dev/null
+++ b/clap/examples/17_yaml.rs
@@ -0,0 +1,53 @@
+// In order to use YAML to define your CLI you must compile clap with the "yaml" feature because
+// it's **not** included by default.
+//
+// In order to do this, ensure your Cargo.toml looks like one of the following:
+//
+// [dependencies.clap]
+// features = ["yaml"]
+//
+// __OR__
+//
+// [dependencies]
+// clap = { features = ["yaml"] }
+
+
+// Using yaml requires calling a clap macro `load_yaml!()` so we must use the '#[macro_use]'
+// directive
+#[macro_use]
+extern crate clap;
+
+#[cfg(feature = "yaml")]
+fn main() {
+ use clap::App;
+
+ // To load a yaml file containing our CLI definition such as the example '17_yaml.yml' we can
+ // use the convenience macro which loads the file at compile relative to the current file
+ // similar to how modules are found.
+ //
+ // Then we pass that yaml object to App to build the CLI.
+ //
+ // Finally we call get_matches() to start the parsing process. We use the matches just as we
+ // normally would
+ let yml = load_yaml!("17_yaml.yml");
+ let m = App::from_yaml(yml).get_matches();
+
+ // Because the example 17_yaml.yml is rather large we'll just look a single arg so you can
+ // see that it works...
+ if let Some(mode) = m.value_of("mode") {
+ match mode {
+ "vi" => println!("You are using vi"),
+ "emacs" => println!("You are using emacs..."),
+ _ => unreachable!()
+ }
+ } else {
+ println!("--mode <MODE> wasn't used...");
+ }
+}
+
+#[cfg(not(feature = "yaml"))]
+fn main() {
+ // As stated above, if clap is not compiled with the YAML feature, it is disabled.
+ println!("YAML feature is disabled.");
+ println!("Pass --features yaml to cargo when trying this example.");
+}
diff --git a/clap/examples/17_yaml.yml b/clap/examples/17_yaml.yml
new file mode 100644
index 0000000..b0d58b3
--- /dev/null
+++ b/clap/examples/17_yaml.yml
@@ -0,0 +1,97 @@
+name: yml_app
+version: "1.0"
+about: an example using a .yml file to build a CLI
+author: Kevin K. <kbknapp@gmail.com>
+
+# AppSettings can be defined as a list and are **not** ascii case sensitive
+settings:
+ - ArgRequiredElseHelp
+
+# All Args must be defined in the 'args:' list where the name of the arg, is the
+# key to a Hash object
+args:
+ # The name of this argument, is 'opt' which will be used to access the value
+ # later in your Rust code
+ - opt:
+ help: example option argument from yaml
+ short: o
+ long: option
+ multiple: true
+ takes_value: true
+ - pos:
+ help: example positional argument from yaml
+ index: 1
+ # A list of possible values can be defined as a list
+ possible_values:
+ - fast
+ - slow
+ - flag:
+ help: demo flag argument
+ short: F
+ multiple: true
+ global: true
+ # Conflicts, mutual overrides, and requirements can all be defined as a
+ # list, where the key is the name of the other argument
+ conflicts_with:
+ - opt
+ requires:
+ - pos
+ - mode:
+ long: mode
+ help: shows an option with specific values
+ # possible_values can also be defined in this list format
+ possible_values: [ vi, emacs ]
+ takes_value: true
+ - mvals:
+ long: mult-vals
+ help: demos an option which has two named values
+ # value names can be described in a list, where the help will be shown
+ # --mult-vals <one> <two>
+ value_names:
+ - one
+ - two
+ - minvals:
+ long: min-vals
+ multiple: true
+ help: you must supply at least two values to satisfy me
+ min_values: 2
+ - maxvals:
+ long: max-vals
+ multiple: true
+ help: you can only supply a max of 3 values for me!
+ max_values: 3
+
+# All subcommands must be listed in the 'subcommand:' object, where the key to
+# the list is the name of the subcommand, and all settings for that command are
+# are part of a Hash object
+subcommands:
+ # The name of this subcommand will be 'subcmd' which can be accessed in your
+ # Rust code later
+ - subcmd:
+ about: demos subcommands from yaml
+ version: "0.1"
+ author: Kevin K. <kbknapp@gmail.com>
+ # Subcommand args are exactly like App args
+ args:
+ - scopt:
+ short: B
+ multiple: true
+ help: example subcommand option
+ takes_value: true
+ - scpos1:
+ help: example subcommand positional
+ index: 1
+
+# ArgGroups are supported as well, and must be sepcified in the 'groups:'
+# object of this file
+groups:
+ # the name of the ArgGoup is specified here
+ - min-max-vals:
+ # All args and groups that are a part of this group are set here
+ args:
+ - minvals
+ - maxvals
+ # setting conflicts is done the same manner as setting 'args:'
+ #
+ # to make this group required, you could set 'required: true' but for
+ # this example we won't do that.
diff --git a/clap/examples/18_builder_macro.rs b/clap/examples/18_builder_macro.rs
new file mode 100644
index 0000000..6bdce47
--- /dev/null
+++ b/clap/examples/18_builder_macro.rs
@@ -0,0 +1,84 @@
+#[macro_use]
+extern crate clap;
+
+// Note, there isn't a need for "use clap::{ ... };" Because the clap_app! macro uses
+// $crate:: internally
+
+fn main() {
+
+ // Validation example testing that a file exists
+ let file_exists = |path| {
+ if std::fs::metadata(path).is_ok() {
+ Ok(())
+ } else {
+ Err(String::from("File doesn't exist"))
+ }
+ };
+
+ // External module may contain this subcommand. If this exists in another module, a function is
+ // required to access it. Recommend `fn clap() -> Clap::SubCommand`.
+ let external_sub_command = clap_app!( @subcommand foo =>
+ (@arg bar: -b "Bar")
+ );
+
+ let matches = clap_app!(MyApp =>
+ (@setting SubcommandRequiredElseHelp)
+ (version: "1.0")
+ (author: "Alice")
+ (about: "Does awesome things")
+ (@arg config: -c --config <conf> #{1, 2} {file_exists} "Sets a custom config file")
+ (@arg proxyHostname: --("proxy-hostname") +takes_value "Sets the hostname of the proxy to use")
+ (@arg input: * "Input file")
+ (@group test =>
+ (@attributes +required)
+ (@arg output: "Sets an optional output file")
+ (@arg debug: -d ... "Turn debugging information on")
+ )
+ (subcommand: external_sub_command)
+ (@subcommand test =>
+ (about: "does testing things")
+ (version: "2.5")
+ (@arg list: -l "Lists test values")
+ (@arg test_req: -r requires[list] "Tests requirement for listing")
+ (@arg aaaa: --aaaa +takes_value {
+ |a| if a.contains('a') {
+ Ok(())
+ } else {
+ Err(String::from("string does not contain at least one a"))
+ }
+ } "Test if the argument contains an a")
+ )
+ ).get_matches();
+
+ // You can check the value provided by positional arguments, or option arguments
+ if let Some(o) = matches.value_of("output") {
+ println!("Value for output: {}", o);
+ }
+
+ if let Some(c) = matches.value_of("config") {
+ println!("Value for config: {}", c);
+ }
+
+ // You can see how many times a particular flag or argument occurred
+ // Note, only flags can have multiple occurrences
+ match matches.occurrences_of("debug") {
+ 0 => println!("Debug mode is off"),
+ 1 => println!("Debug mode is kind of on"),
+ 2 => println!("Debug mode is on"),
+ 3 | _ => println!("Don't be crazy"),
+ }
+
+ // You can check for the existence of subcommands, and if found use their
+ // matches just as you would the top level app
+ if let Some(matches) = matches.subcommand_matches("test") {
+ // "$ myapp test" was run
+ if matches.is_present("list") {
+ // "$ myapp test -l" was run
+ println!("Printing testing lists...");
+ } else {
+ println!("Not printing testing lists...");
+ }
+ }
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/19_auto_authors.rs b/clap/examples/19_auto_authors.rs
new file mode 100644
index 0000000..afbb985
--- /dev/null
+++ b/clap/examples/19_auto_authors.rs
@@ -0,0 +1,15 @@
+#[macro_use]
+extern crate clap;
+
+use clap::App;
+
+fn main() {
+ App::new("myapp")
+ .about("does awesome things")
+ // use crate_authors! to pull the author(s) names from the Cargo.toml
+ .author(crate_authors!())
+ .get_matches();
+
+ // running this app with -h will display whatever author(s) are in your
+ // Cargo.toml
+}
diff --git a/clap/examples/20_subcommands.rs b/clap/examples/20_subcommands.rs
new file mode 100644
index 0000000..f80f46d
--- /dev/null
+++ b/clap/examples/20_subcommands.rs
@@ -0,0 +1,143 @@
+// Working with subcommands is simple. There are a few key points to remember when working with
+// subcommands in clap. First, SubCommands are really just Apps. This means they can have their own
+// settings, version, authors, args, and even their own subcommands. The next thing to remember is
+// that subcommands are set up in a tree like hierarchy.
+//
+// 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 explanation easier)
+//
+// 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):
+//
+// $ 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
+//
+// It's also important to know that subcommands each have their own set of matches and may have args
+// with the same name as other subcommands in a different part of the tree hierarchy (i.e. the arg
+// names aren't in a flat namespace).
+//
+// In order to use subcommands in clap, you only need to know which subcommand you're at in your
+// tree, and which args are defined on that subcommand.
+//
+// Let's make a quick program to illustrate. We'll be using the same example as above but for
+// brevity sake we won't implement all of the subcommands, only a few.
+
+extern crate clap;
+
+use clap::{App, Arg, SubCommand, AppSettings};
+
+fn main() {
+
+ let matches = App::new("git")
+ .about("A fictional versioning CLI")
+ .version("1.0")
+ .author("Me")
+ .subcommand(SubCommand::with_name("clone")
+ .about("clones repos")
+ .arg(Arg::with_name("repo")
+ .help("The repo to clone")
+ .required(true)))
+ .subcommand(SubCommand::with_name("push")
+ .about("pushes things")
+ .setting(AppSettings::SubcommandRequiredElseHelp)
+ .subcommand(SubCommand::with_name("remote") // Subcommands can have their own subcommands,
+ // which in turn have their own subcommands
+ .about("pushes remote things")
+ .arg(Arg::with_name("repo")
+ .required(true)
+ .help("The remote repo to push things to")))
+ .subcommand(SubCommand::with_name("local")
+ .about("pushes local things")))
+ .subcommand(SubCommand::with_name("add")
+ .about("adds things")
+ .author("Someone Else") // Subcommands can list different authors
+ .version("v2.0 (I'm versioned differently") // or different version from their parents
+ .setting(AppSettings::ArgRequiredElseHelp) // They can even have different settings
+ .arg(Arg::with_name("stuff")
+ .long("stuff")
+ .help("Stuff to add")
+ .takes_value(true)
+ .multiple(true)))
+ .get_matches();
+
+ // At this point, the matches we have point to git. Keep this in mind...
+
+ // You can check if one of git's subcommands was used
+ if matches.is_present("clone") {
+ println!("'git clone' was run.");
+ }
+
+ // You can see which subcommand was used
+ if let Some(subcommand) = matches.subcommand_name() {
+ println!("'git {}' was used", subcommand);
+
+ // It's important to note, this *only* check's git's DIRECT children, **NOT** it's
+ // grandchildren, great grandchildren, etc.
+ //
+ // i.e. if the command `git push remove --stuff foo` was run, the above will only print out,
+ // `git push` was used. We'd need to get push's matches to see further into the tree
+ }
+
+ // An alternative to checking the name is matching on known names. Again notice that only the
+ // direct children are matched here.
+ match matches.subcommand_name() {
+ Some("clone") => println!("'git clone' was used"),
+ Some("push") => println!("'git push' was used"),
+ Some("add") => println!("'git add' was used"),
+ None => println!("No subcommand was used"),
+ _ => unreachable!(), // Assuming you've listed all direct children above, this is unreachable
+ }
+
+ // You could get the independent subcommand matches, although this is less common
+ if let Some(clone_matches) = matches.subcommand_matches("clone") {
+ // Now we have a reference to clone's matches
+ println!("Cloning repo: {}", clone_matches.value_of("repo").unwrap());
+ }
+
+ // The most common way to handle subcommands is via a combined approach using
+ // `ArgMatches::subcommand` which returns a tuple of both the name and matches
+ match matches.subcommand() {
+ ("clone", Some(clone_matches)) =>{
+ // Now we have a reference to clone's matches
+ println!("Cloning {}", clone_matches.value_of("repo").unwrap());
+ },
+ ("push", Some(push_matches)) =>{
+ // Now we have a reference to push's matches
+ match push_matches.subcommand() {
+ ("remote", Some(remote_matches)) =>{
+ // Now we have a reference to remote's matches
+ println!("Pushing to {}", remote_matches.value_of("repo").unwrap());
+ },
+ ("local", Some(_)) =>{
+ println!("'git push local' was used");
+ },
+ _ => unreachable!(),
+ }
+ },
+ ("add", Some(add_matches)) =>{
+ // Now we have a reference to add's matches
+ println!("Adding {}", add_matches.values_of("stuff").unwrap().collect::<Vec<_>>().join(", "));
+ },
+ ("", None) => println!("No subcommand was used"), // If no subcommand was used it'll match the tuple ("", None)
+ _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable!()
+ }
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/21_aliases.rs b/clap/examples/21_aliases.rs
new file mode 100644
index 0000000..3be0445
--- /dev/null
+++ b/clap/examples/21_aliases.rs
@@ -0,0 +1,39 @@
+extern crate clap;
+
+use clap::{App, Arg, SubCommand};
+
+fn main() {
+
+ let matches = App::new("MyApp")
+ .subcommand(SubCommand::with_name("ls")
+ .aliases(&["list", "dir"])
+ .about("Adds files to myapp")
+ .version("0.1")
+ .author("Kevin K.")
+ .arg(Arg::with_name("input")
+ .help("the file to add")
+ .index(1)
+ .required(true))
+ )
+ .get_matches();
+
+ // You can check if a subcommand was used like normal
+ if matches.is_present("add") {
+ println!("'myapp add' was run.");
+ }
+
+ // You can get the independent subcommand matches (which function exactly like App matches)
+ if let Some(matches) = matches.subcommand_matches("add") {
+ // Safe to use unwrap() because of the required() option
+ println!("Adding file: {}", matches.value_of("input").unwrap());
+ }
+
+ // You can also match on a subcommand's name
+ match matches.subcommand_name() {
+ Some("add") => println!("'myapp add' was used"),
+ None => println!("No subcommand was used"),
+ _ => println!("Some other subcommand was used"),
+ }
+
+ // Continued program logic goes here...
+}
diff --git a/clap/examples/22_stop_parsing_with_--.rs b/clap/examples/22_stop_parsing_with_--.rs
new file mode 100644
index 0000000..a5ba5b3
--- /dev/null
+++ b/clap/examples/22_stop_parsing_with_--.rs
@@ -0,0 +1,25 @@
+extern crate clap;
+
+use clap::{App, Arg};
+
+/// myprog -f -p=bob -- sloppy slop slop
+fn main() {
+
+ let matches = App::new("myprog")
+ .arg(Arg::with_name("eff")
+ .short("f"))
+ .arg(Arg::with_name("pea")
+ .short("p")
+ .takes_value(true))
+ .arg(Arg::with_name("slop")
+ .multiple(true)
+ .last(true))
+ .get_matches();
+
+
+ println!("-f used: {:?}", matches.is_present("eff"));
+ println!("-p's value: {:?}", matches.value_of("pea"));
+ println!("'slops' values: {:?}", matches.values_of("slop").map(|vals| vals.collect::<Vec<_>>()));
+
+ // Continued program logic goes here...
+}