aboutsummaryrefslogtreecommitdiff
path: root/clap/examples/20_subcommands.rs
diff options
context:
space:
mode:
Diffstat (limited to 'clap/examples/20_subcommands.rs')
-rw-r--r--clap/examples/20_subcommands.rs143
1 files changed, 0 insertions, 143 deletions
diff --git a/clap/examples/20_subcommands.rs b/clap/examples/20_subcommands.rs
deleted file mode 100644
index f80f46d..0000000
--- a/clap/examples/20_subcommands.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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...
-}