1 use std::ffi::OsString;
2 use std::path::PathBuf;
3
4 use clap::{Args, Parser, Subcommand};
5
6 /// A fictional versioning CLI
7 #[derive(Debug, Parser)] // requires `derive` feature
8 #[clap(name = "git")]
9 #[clap(about = "A fictional versioning CLI", long_about = None)]
10 struct Cli {
11 #[clap(subcommand)]
12 command: Commands,
13 }
14
15 #[derive(Debug, Subcommand)]
16 enum Commands {
17 /// Clones repos
18 #[clap(arg_required_else_help = true)]
19 Clone {
20 /// The remote to clone
21 #[clap(value_parser)]
22 remote: String,
23 },
24 /// pushes things
25 #[clap(arg_required_else_help = true)]
26 Push {
27 /// The remote to target
28 #[clap(value_parser)]
29 remote: String,
30 },
31 /// adds things
32 #[clap(arg_required_else_help = true)]
33 Add {
34 /// Stuff to add
35 #[clap(required = true, value_parser)]
36 path: Vec<PathBuf>,
37 },
38 Stash(Stash),
39 #[clap(external_subcommand)]
40 External(Vec<OsString>),
41 }
42
43 #[derive(Debug, Args)]
44 #[clap(args_conflicts_with_subcommands = true)]
45 struct Stash {
46 #[clap(subcommand)]
47 command: Option<StashCommands>,
48
49 #[clap(flatten)]
50 push: StashPush,
51 }
52
53 #[derive(Debug, Subcommand)]
54 enum StashCommands {
55 Push(StashPush),
56 Pop {
57 #[clap(value_parser)]
58 stash: Option<String>,
59 },
60 Apply {
61 #[clap(value_parser)]
62 stash: Option<String>,
63 },
64 }
65
66 #[derive(Debug, Args)]
67 struct StashPush {
68 #[clap(short, long, value_parser)]
69 message: Option<String>,
70 }
71
main()72 fn main() {
73 let args = Cli::parse();
74
75 match args.command {
76 Commands::Clone { remote } => {
77 println!("Cloning {}", remote);
78 }
79 Commands::Push { remote } => {
80 println!("Pushing to {}", remote);
81 }
82 Commands::Add { path } => {
83 println!("Adding {:?}", path);
84 }
85 Commands::Stash(stash) => {
86 let stash_cmd = stash.command.unwrap_or(StashCommands::Push(stash.push));
87 match stash_cmd {
88 StashCommands::Push(push) => {
89 println!("Pushing {:?}", push);
90 }
91 StashCommands::Pop { stash } => {
92 println!("Popping {:?}", stash);
93 }
94 StashCommands::Apply { stash } => {
95 println!("Applying {:?}", stash);
96 }
97 }
98 }
99 Commands::External(args) => {
100 println!("Calling out to {:?} with {:?}", &args[0], &args[1..]);
101 }
102 }
103
104 // Continued program logic goes here...
105 }
106