Default Subcommand #3566
-
Is there a way for For example, I want to be able to use both
and also
where "create" is assumed to be the default subcommand. However, when a different subcommand is specified, the default subcommand does not go into effect. For example:
Is there any stable or unstable item in the API to implement the above? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 9 replies
-
At the moment there is not. You can do it manually though. Something like let cmd = clap::Command::new("git")
.subcommand(
clap::Command::new("stash")
.args_conflicts_with_subcommands(true)
.args(push_args())
.subcommand(clap::Command::new("push").args(push_args()))
);
let matches = cmd.get_matches();
match matches.subcommand() {
Some(("stash", sub_matches)) => match sub_matches.subcommand() {
Some(("push"), sub_matches)) => push(sub_matches),
None => push(sub_matches),
}
} We should probably add this to our "git" example. |
Beta Was this translation helpful? Give feedback.
-
FYI #4350 was merged which should simplify some default subcommand cases (the flattened struct can have required fields now) |
Beta Was this translation helpful? Give feedback.
-
Is there currently a way to do this with a required argument (like in What I try to achieve is, having two subcommands But the main entry point has a required argument, as the application would not work correctly without it. So I need some way of telling clap "ignore any required fields if a subcommand is present, but not otherwise". This is a very simplified version: // cli.rs
#[derive(Parser)]
pub struct Cli {
#[command(subcommand)]
pub cmd: Option<Command>,
#[command(flatten)]
pub run: Option<Run>,
}
#[derive(Subcommand)]
pub enum Command {
Run(Run),
Completions {
#[arg(value_enum)]
shell: Shell,
},
Manpages {
#[arg(value_hint = ValueHint::DirPath)]
dir: PathBuf,
}
}
#[derive(Args)]
pub struct Run {
#[arg(short, long, value_hint = ValueHint::FilePath)]
pub input: PathBuf,
// further optional args omitted for simplicity
} Then calling it as follows: // main.rs
mod cli;
fn main() {
let cli = Cli::parse();
let cmd = cli.cmd.or_else(|| cli.run.map(Command::Run)).unwrap();
// don't really like the unwrap, but we can really make `run` a non-Option, right?
map cmd {
// ...
}
} Now, when trying to run the completions for example, it still requires
Is there any special option that I'm missing to make it ignore the |
Beta Was this translation helpful? Give feedback.
At the moment there is not. You can do it manually though. Something like
We should probably add this to our "git" example.