I'd like to accept an argument like --nums 1.0,2.0,3.0, which is parsed into a Vec<f64> member. My initial approach was to use something like this:
use std::num::ParseFloatError;
use structopt::StructOpt;
fn parse_list(s: &str) -> Result<Vec<f64>, ParseFloatError> {
s.split(",").map(|s| s.parse()).collect()
}
#[derive(StructOpt)]
#[structopt(name = "app")]
struct CliOptions {
#[structopt(long = "nums", default_value = "1.0", parse(try_from_str = "parse_list"))]
num_tail_syms: Vec<f64>,
}
Unfortunately this does not work, because Vec<f64> is handled specially: It is interpreted as a repeatable argument each accepting a value of type f64. I've worked around this by using Option<Vec<f64>> instead and manually performing a .unwrap_or(Vec::new()).
I'm wondering if there is a way to do this (without abusing Option<_>) that I missed, or otherwise if it would be worthwhile to support it?
Clean version: use https://docs.rs/clap/2.31.2/clap/struct.Arg.html#method.use_delimiter
To work around (with a quite dirty hack) the automatic Vec handling, you can type VecFloat = Vec<f64> and then use VecFloat in your struct, the vector will not be detected.
Maybe custom toggling of collect can be an interesting feature, related to #79
Using
struct CliOptions {
#[structopt(long = "nums", default_value = "1.0", raw(use_delimiter = "true"))]
num_tail_syms: Vec<f64>,
}
works perfectly, thanks! With the type-alias workaround for the more general case, I guess this can be closed.
Most helpful comment
Using
works perfectly, thanks! With the type-alias workaround for the more general case, I guess this can be closed.