Reputation: 93
Trying to use a struct within a struct in clap
:
use clap::{Args, Parser};
use std::path::PathBuf;
#[derive(Parser, Debug)]
enum Command {
Foo(Foo),
}
#[derive(Args, Debug)]
struct Foo {
bar: Option<Bar>,
path: PathBuf,
}
#[derive(Parser, Clone, Debug)]
struct Bar {
bla: u8,
bla_2: String,
}
fn main() {
let cli = Command::parse();
println!("cli {:#?}", cli);
}
So I could call the app with the following options: cargo run -- foo bar 42 baz /tmp/a
or just cargo run -- foo /tmp/a
since the bar
argument is optional.
However, currently it does not build:
--> src/main.rs:11:5
|
11 | bar: Option<Bar>,
| ^^^ the trait `FromStr` is not implemented for `Bar`
|
And since the values within Bar
have to be space-separated implementing a FromStr
would not do the trick anyway.
Is it even possible to do something of this fashion in clap
currently?
Upvotes: 2
Views: 4305
Reputation: 22738
There are several problems with your code. The biggest one is:
This is a problem in your case because your command line looks like this:
cargo run -- <required> [optional] /tmp/a
If you have a required path at the end, there can not be an optional positional argument before that.
Further problems:
#[derive(Parser)]
should be attached to a struct
, not an enum
.#[derive(Parser)]
, which represents the entry object of your arguments parser.I'm unsure how else to help you, except pointing out your problems. If the invocations cargo run -- foo bar 42 baz /tmp/a
and cargo run -- foo /tmp/a
are non-negotiable, I don't think clap
is the right library for you; I think you should parse by hand.
Upvotes: 1