diff options
Diffstat (limited to 'clap/examples/20_subcommands.rs')
-rw-r--r-- | clap/examples/20_subcommands.rs | 143 |
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... -} |