0

I'm using the structopt crate and I have the following struct:

#[derive(Clone, StructOpt, Debug)]
#[structopt(name = "test")]
pub struct CommandlineOptions {
    #[structopt(
    long = "length",
    help = "The length of the the string to generate",
    default_value = "50",
    index = 1
    )]
    pub length: usize,
}


let options = CommandlineOptions::from_args();

If options.length is 50, how can I know it comes from the default value 50, or the user provided a value of 50?

Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
Just a learner
  • 26,690
  • 50
  • 155
  • 234
  • 1
    If you want to know that (FWR) you may should use an `Option` and check if that's `None`. – hellow Sep 09 '21 at 14:21

1 Answers1

2

I don't think it is possible to do this with structopt. The idiomatic way to solve this problem is to instead use an Option<usize> instead of usize (as documented here):

use structopt::StructOpt;

#[derive(Clone, StructOpt, Debug)]
#[structopt(name = "test")]
pub struct CommandlineOptions {
    #[structopt(
    long = "length",
    help = "The length of the the string to generate",
    index = 1
    )]
    pub length: Option<usize>,
}

fn main() {
    let options = CommandlineOptions::from_args();
    println!("Length parameter was supplied: {}, length (with respect to default): {}", options.length.is_some(), options.length.unwrap_or(50));
}

If this does not work in your case somehow, you could also directly work with the clap::ArgMatches struct (structopt is little more than macro magic around clap) to check the number of occurrences of length with ArgMatches::occurrences_of. However, this wouldn't be very idiomatic.

use structopt::StructOpt;

#[derive(Clone, StructOpt, Debug)]
#[structopt(name = "test")]
pub struct CommandlineOptions {
    #[structopt(
    long = "length",
    help = "The length of the the string to generate",
    default_value = "50",
    index = 1
    )]
    pub length: usize,
}

fn main() {
    let matches = CommandlineOptions::clap().get_matches();
    let options = CommandlineOptions::from_clap(&matches);
    
    let length_was_supplied = match matches.occurrences_of("length") {
        0 => false,
        1 => true,
        other => panic!("Number of occurrences is neither 0 nor 1, but {}. This should never happen.", other)
    };
    
    println!("Length parameter was supplied: {}, length (with respect to default): {}", length_was_supplied, options.length);
}
Elias Holzmann
  • 3,216
  • 2
  • 17
  • 33