allan
June 29, 2025, 3:22pm
1
Hi folks,
I figured out that using Clap I can parse a vector of enum (code below) and then run the program with --myarg first --myarg second --myarg first
.
But is it possible to parse vector of vectors (Vec<Vec<MyEnum>>
or Vec<Vec<String>>
)? I'm not sure how exactly this would be specified as arguments but I'm OK with any style as long as I can get group of groups (vector of vectors).
Thank you.
#[derive(Clone, Debug, clap::ValueEnum)]
enum MyEnum {
First,
Second,
Third,
}
#[derive(Clone, Debug, clap::Parser)]
#[command(name = "program", about = "program", rename_all = "snake_case")]
struct Xyz {
#[arg(long, value_enum)]
myarg: Vec<MyEnum>,
}
pub async fn runit() {
let Xyz { myarg, .. } = <Xyz as clap::Parser>::parse();
myarg.iter().enumerate().for_each(|(i, inp)| {
println!(" {i}. {inp:?}");
});
}
To prevent risking an XY situation, can you give an example of what exactly you're trying to do?
1 Like
allan
June 29, 2025, 4:59pm
3
Hello,
Just need to group multiple arguments into multiple groups - Vec<Vec<x>
would be ideal.
To test it:
myarg.iter().enumerate().for_each(|(i, x)| {
x.iter().enumerate().for_each(|(i2, y)| {
println!(" {i}.{i2}. {y}");
});
});
jofas
June 29, 2025, 5:02pm
4
If you care for using commas as the delimiter for the nested vectors, you can do this:
use clap::ValueEnum;
#[derive(Clone, Debug, ValueEnum)]
enum MyEnum {
First,
Second,
Third,
}
#[derive(Clone, Debug, clap::Parser)]
#[command(name = "program", about = "program", rename_all = "snake_case")]
struct Xyz {
#[arg(long, value_parser = parse_my_enum_vec)]
myarg: Vec<Vec<MyEnum>>,
}
fn parse_my_enum_vec(s: &str) -> Result<Vec<MyEnum>, String> {
let mut res = Vec::new();
for x in s.split(',') {
res.push(MyEnum::from_str(x, true)?);
}
Ok(res)
}
fn main() {
let res = <Xyz as clap::Parser>::try_parse_from([
"playground",
"--myarg",
"first,second,first",
"--myarg",
"third",
]);
println!("{res:?}");
}
Playground.
3 Likes
allan
June 29, 2025, 5:11pm
5
That's fantastic! Thank you!
1 Like