40

I'm using the Clap crate for parsing command line parameters. I've defined a subcommand ls that should list files. Clap also defines a help subcommand that displays information about the application and its usage.

If no command is provided, nothing gets displayed at all, but I want the app to display help in that case.

I've tried this code, which looks pretty straightforward, but it doesn't work:

extern crate clap;

use clap::{App, SubCommand};

fn main() {
    let mut app = App::new("myapp")
        .version("0.0.1")
        .about("My first CLI APP")
        .subcommand(SubCommand::with_name("ls").about("List anything"));
    let matches = app.get_matches();

    if let Some(cmd) = matches.subcommand_name() {
        match cmd {
            "ls" => println!("List something here"),
            _ => eprintln!("unknown command"),
        }
    } else {
        app.print_long_help();
    }
}

I get an error that app is used after move:

error[E0382]: use of moved value: `app`
  --> src/main.rs:18:9
   |
10 |     let matches = app.get_matches();
   |                   --- value moved here
...
18 |         app.print_long_help();
   |         ^^^ value used here after move
   |
   = note: move occurs because `app` has type `clap::App<'_, '_>`, which does not implement the `Copy` trait

Reading through the documentation of Clap, I've found that the clap::ArgMatches that's returned in get_matches() has a method usage that returns the string for usage part, but, unfortunately, only this part and nothing else.

billkw
  • 3,350
  • 3
  • 28
  • 32
rpeshkov
  • 4,877
  • 3
  • 27
  • 43

3 Answers3

43

Use clap::AppSettings::ArgRequiredElseHelp:

App::new("myprog")
    .setting(AppSettings::ArgRequiredElseHelp)

See also:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • thanks for your answer. It works great! Also, thanks for the related answer. Found a lot of useful information there. – rpeshkov Mar 15 '18 at 10:27
  • 8
    Just note that: "`Setting Arg::default_value` effectively disables this option as it will ensure that some argument is always present." `SubcommandRequiredElseHelp` might be a better option for some apps. – Ondrej Slinták Jun 23 '19 at 13:20
3

You can also use Command::arg_required_else_help as a bool on the command itself.

Command::new("rule").arg_required_else_help(true)
Peter Girnus
  • 2,673
  • 1
  • 19
  • 24
3

If you are using the derive instead of the builder API you can set the flag mentioned by shepmaster as follows:

#[command(arg_required_else_help = true)]
pub struct Cli {

    #[clap(short)]
    pub init: bool,

See also: https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html#configuring-the-parser

grmmgrmm
  • 994
  • 10
  • 29