eonil
eonil

Reputation: 86095

How to attach possible_values to a struct with structopt?

clap allows you to provide list of accepted values using possible_values like this.

let mode_vals = ["fast", "slow"];
.possible_values(&mode_vals)

How to do this with structopt?

Upvotes: 7

Views: 2367

Answers (2)

Guigo2k
Guigo2k

Reputation: 81

Since structopt 0.3, you can use any method from App and Arg directly:

const MODE_VALS: &[&str] = &["fast", "slow"];

#[derive(StructOpt, Debug)]
struct Opt {
    /// The velocity mode
    #[structopt(short, long, possible_values(MODE_VALS))]
    mode: String,
}

https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md#raw-attributes-are-removed-198-by-sphynx

Upvotes: 8

ticky
ticky

Reputation: 167

clap’s possible_values is exposed as a field option, as shown in this structopt example:

//! How to use `arg_enum!` with `StructOpt`.

use clap::arg_enum;
use structopt::StructOpt;

arg_enum! {
    #[derive(Debug)]
    enum Baz {
        Foo,
        Bar,
        FooBar
    }
}

#[derive(StructOpt, Debug)]
struct Opt {
    /// Important argument.
    #[structopt(possible_values = &Baz::variants(), case_insensitive = true)]
    i: Baz,
}

fn main() {
    let opt = Opt::from_args();
    println!("{:?}", opt);
}

Notably, this is making use of case_insensitive as well, to allow any case of those variants to be accepted.

If you want more granular control, you could omit case_insensitive and instead implement the variants yourself:

use structopt::StructOpt;

#[derive(Debug)]
enum Baz {
    Foo,
    Bar,
    FooBar
}

impl Baz {
    fn variants() -> [&'static str; 3] {
        ["foo", "bar", "foo-bar"]
    }
}

#[derive(StructOpt, Debug)]
struct Opt {
    /// Important argument.
    #[structopt(possible_values = &Baz::variants())]
    i: Baz,
}

fn main() {
    let opt = Opt::from_args();
    println!("{:?}", opt);
}

Finally, you could also use a string array in the same manner.

Upvotes: 1

Related Questions