diff options
Diffstat (limited to 'vendor/clap/examples/git.rs')
-rw-r--r-- | vendor/clap/examples/git.rs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/clap/examples/git.rs b/vendor/clap/examples/git.rs new file mode 100644 index 0000000..fc8fd01 --- /dev/null +++ b/vendor/clap/examples/git.rs @@ -0,0 +1,138 @@ +use std::ffi::OsString; +use std::path::PathBuf; + +use clap::{arg, Command}; + +fn cli() -> Command { + Command::new("git") + .about("A fictional versioning CLI") + .subcommand_required(true) + .arg_required_else_help(true) + .allow_external_subcommands(true) + .subcommand( + Command::new("clone") + .about("Clones repos") + .arg(arg!(<REMOTE> "The remote to clone")) + .arg_required_else_help(true), + ) + .subcommand( + Command::new("diff") + .about("Compare two commits") + .arg(arg!(base: [COMMIT])) + .arg(arg!(head: [COMMIT])) + .arg(arg!(path: [PATH]).last(true)) + .arg( + arg!(--color <WHEN>) + .value_parser(["always", "auto", "never"]) + .num_args(0..=1) + .require_equals(true) + .default_value("auto") + .default_missing_value("always"), + ), + ) + .subcommand( + Command::new("push") + .about("pushes things") + .arg(arg!(<REMOTE> "The remote to target")) + .arg_required_else_help(true), + ) + .subcommand( + Command::new("add") + .about("adds things") + .arg_required_else_help(true) + .arg(arg!(<PATH> ... "Stuff to add").value_parser(clap::value_parser!(PathBuf))), + ) + .subcommand( + Command::new("stash") + .args_conflicts_with_subcommands(true) + .flatten_help(true) + .args(push_args()) + .subcommand(Command::new("push").args(push_args())) + .subcommand(Command::new("pop").arg(arg!([STASH]))) + .subcommand(Command::new("apply").arg(arg!([STASH]))), + ) +} + +fn push_args() -> Vec<clap::Arg> { + vec![arg!(-m --message <MESSAGE>)] +} + +fn main() { + let matches = cli().get_matches(); + + match matches.subcommand() { + Some(("clone", sub_matches)) => { + println!( + "Cloning {}", + sub_matches.get_one::<String>("REMOTE").expect("required") + ); + } + Some(("diff", sub_matches)) => { + let color = sub_matches + .get_one::<String>("color") + .map(|s| s.as_str()) + .expect("defaulted in clap"); + + let mut base = sub_matches.get_one::<String>("base").map(|s| s.as_str()); + let mut head = sub_matches.get_one::<String>("head").map(|s| s.as_str()); + let mut path = sub_matches.get_one::<String>("path").map(|s| s.as_str()); + if path.is_none() { + path = head; + head = None; + if path.is_none() { + path = base; + base = None; + } + } + let base = base.unwrap_or("stage"); + let head = head.unwrap_or("worktree"); + let path = path.unwrap_or(""); + println!("Diffing {base}..{head} {path} (color={color})"); + } + Some(("push", sub_matches)) => { + println!( + "Pushing to {}", + sub_matches.get_one::<String>("REMOTE").expect("required") + ); + } + Some(("add", sub_matches)) => { + let paths = sub_matches + .get_many::<PathBuf>("PATH") + .into_iter() + .flatten() + .collect::<Vec<_>>(); + println!("Adding {paths:?}"); + } + Some(("stash", sub_matches)) => { + let stash_command = sub_matches.subcommand().unwrap_or(("push", sub_matches)); + match stash_command { + ("apply", sub_matches) => { + let stash = sub_matches.get_one::<String>("STASH"); + println!("Applying {stash:?}"); + } + ("pop", sub_matches) => { + let stash = sub_matches.get_one::<String>("STASH"); + println!("Popping {stash:?}"); + } + ("push", sub_matches) => { + let message = sub_matches.get_one::<String>("message"); + println!("Pushing {message:?}"); + } + (name, _) => { + unreachable!("Unsupported subcommand `{name}`") + } + } + } + Some((ext, sub_matches)) => { + let args = sub_matches + .get_many::<OsString>("") + .into_iter() + .flatten() + .collect::<Vec<_>>(); + println!("Calling out to {ext:?} with {args:?}"); + } + _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable!() + } + + // Continued program logic goes here... +} |