rust 在clap中使用结构作为命令行参数

gr8qqesn  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(149)

尝试在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);
}

因此,我可以使用以下选项调用该应用程序:cargo run -- foo bar 42 baz /tmp/acargo run -- foo /tmp/a,因为bar参数是可选的。
但是,目前它并不构建:

--> src/main.rs:11:5
   |
11 |     bar: Option<Bar>,
   |     ^^^ the trait `FromStr` is not implemented for `Bar`
   |

而且由于Bar中的值必须用空格分隔,因此实现FromStr无论如何都不会达到目的。
目前在clap中是否有可能做这种事情?

n9vozmp4

n9vozmp41#

你的代码有几个问题。最大的一个是:

  • 可选的位置项不能必需的位置参数之前

这是一个问题,因为你的命令行看起来像这样:

cargo run -- <required> [optional] /tmp/a

如果你在末尾有一个必需的路径,在它之前不能有一个可选的位置参数。
其他问题:

  • #[derive(Parser)]应该连接到struct,而不是enum
  • 应该只有一个#[derive(Parser)],它表示参数解析器的入口对象。

如果cargo run -- foo bar 42 baz /tmp/acargo run -- foo /tmp/a的调用是不可协商的,我认为clap不是适合你的库;我认为你应该用手来解析。

相关问题