BitTickler
BitTickler

Reputation: 11927

clap default value - how to use it

Playing with Rusts clap crate for the first time. And I wonder how to use the default value of a command line option, when the option was not specified at the command line.

Given I specified a default_value in the yaml file (see snippet below), I expected the matches.value_of("VERBOSE") to return the default value if there is no other value given in the command line.

Instead, I get:

thread 'main' panicked at 'called Option::unwrap() on a None value', src/main.rs:18:6

I was googling for a while but it seems, no one really gives a canonical example of how it is supposed to work.

...
args:
  - config:
      short: c
      long: config
      value_name: CONFIG
      help: Specifies the config file to use.
      takes_value: true
      default_value: ""
  - verbose:
      short: v
      long: verbose
      value_name: VERBOSE
      help: Sets verbosity. 0 = silent, > 0 = verbose.
      takes_value: true
      default_value: "1"

Here, my feeble attempt... compiling but not working (panics if empty command line is used).

// ...
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();
    let verbosity =
    matches.value_of("VERBOSE")
    .and_then(|s| s.parse::<u8>().ok())
    .unwrap();

As this obviously does not use the default values, my simple question is: How do I do it right?

Upvotes: 7

Views: 13992

Answers (1)

frankenapps
frankenapps

Reputation: 8271

The problem is you either have a small misconception about what value_name (which is used only for the CLI help option) is, or you missed, that the argument names are case sensitive.

You have two options to make this work as expected:

  1. Use the lowercase argument name as specified in the YAML (change .rs):

YAML:

...
args:
  - config:
      short: c
      long: config
      value_name: CONFIG
      help: Specifies the config file to use.
      takes_value: true
      default_value: "1"
  - verbose:
      short: v
      long: verbose
      value_name: VERBOSE
      help: Sets verbosity. 0 = silent, > 0 = verbose.
      takes_value: true
      default_value: "1"

Rust:

use clap::{load_yaml, App};

fn main() {
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();
    let verbosity =
    matches.value_of("verbose")
    .and_then(|s| s.parse::<u8>().ok())
    .unwrap();
    println!("{}", verbosity);
}
  1. Use the uppercase name as specified in the Code (change .yaml): YAML:
...
args:
  - config:
      short: c
      long: config
      value_name: CONFIG
      help: Specifies the config file to use.
      takes_value: true
      default_value: "1"
  - VERBOSE:
      short: v
      long: verbose
      value_name: VERBOSE
      help: Sets verbosity. 0 = silent, > 0 = verbose.
      takes_value: true
      default_value: "1"

Rust

use clap::{load_yaml, App};

fn main() {
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();
    let verbosity =
    matches.value_of("VERBOSE")
    .and_then(|s| s.parse::<u8>().ok())
    .unwrap();
    println!("{}", verbosity);
}

Upvotes: 7

Related Questions