Search code examples
rustclap

How to specify the default value for a vector argument with Clap 4


I have the following type:

#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Processor {
    DefaultProcessor,
    SecondaryProcessor,
}

I have a FromStr impl for this struct as well (not shown because it's very simple).

I am currently using this in a struct like this:

#[derive(Parser)]
pub struct RunLocalTestnet {
    /// Processors to run.
    #[clap(long)]
    processors: Vec<Processor>,
}

So far so good, this works great. What I'm trying to do now is add a default value for this vector, for example:

    #[clap(long, default_value_t = vec![Processor::DefaultProcessor])]
    processors: Vec<Processor>,

Unfortunately when I do this I get the following error:

error[E0277]: `Vec<processor::processors::Processor>` doesn't implement `std::fmt::Display`
   --> crates/aptos/src/node/local_testnet.rs:103:18
    |
103 |     #[clap(long, default_value_t = vec![Processor::DefaultProcessor])]
    |                  ^^^^^^^^^^^^^^^ `Vec<processor::processors::Processor>` cannot be formatted with the default formatter
    |
    = help: the trait `std::fmt::Display` is not implemented for `Vec<processor::processors::Processor>`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
    = note: required for `Vec<processor::processors::Processor>` to implement `ToString`

Is there a way to make this work with Clap 4 (specifically 4.3.9) out of the box? I feel like it shouldn't be necessary to make Processor impl Display because it works up until I set the default value.


Solution

  • I believe you want default_values_t (note the s). default_value_t requires the type to implement Display or ValueEnum which of course Vec<T> does not. But default_values_t requires the type to be a Vec<T> where only T has to implement Display or ValueEnum, which is exactly what you have.

    Docs page: https://docs.rs/clap/4.3.9/clap/_derive/index.html