【问题标题】:StructOpt - how to provide a default value for a Vec?StructOpt - 如何为 Vec 提供默认值?
【发布时间】:2020-08-26 06:56:24
【问题描述】:

我正在寻找一种方法来默认使用多个项目初始化 structopt Vec 字段。我可以为单个项目做到这一点:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
pub struct Cli {
    #[structopt(default_value = "foo")]
    foo: Vec<String>,
}

fn main() {
    let cli = Cli::from_iter(Vec::<String>::new());
    assert_eq!(cli.foo, vec!["foo"]);
}

但是如何使cli.foo 等于默认情况下假设vec!["foo", "bar"]

【问题讨论】:

  • 你可以通过显式实现Default 来为成员的包装类型实现这一点,参见docs。据我所知,您需要自己实现 Display 和朋友(FromStr,ToString,...)。
  • @L.Riemer 谢谢,FromStr 似乎就足够了(作为答案发布)
  • 这与我的想法有点不同,不过应该也可以。
  • @L.Riemer 有时间你会发布解决方案吗?我是 rust 新手,所以我可能遗漏了一些东西。
  • 完全没有必要这样做。您的解决方案很好,并且定义明确。实现FromStr 告诉编译器如何将(default_value = "foo,bar", long) 中的"foo,bar" 转换为包装器类型(以及如何从cli 解析)。相反,我会为包装器类型编写 (default_value, long) 并实现 Default,但这是个人喜好问题。顺便说一句,你可以接受你的答案。

标签: rust structopt


【解决方案1】:

我遵循了 L. Riemer 的建议,似乎只实现 FromStr 就足够了:

use structopt::StructOpt;

#[derive(Debug, PartialEq)]
struct Foo(Vec<String>);

impl std::str::FromStr for Foo {
    type Err = Box<dyn std::error::Error>;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Foo(s.split(",").map(|x| x.trim().to_owned()).collect()))
    }
}

#[derive(StructOpt)]
pub struct Cli {
    #[structopt(long, default_value = "foo, bar")]
    foo: Foo,
}

fn main() {
    let cli = Cli::from_iter(Vec::<String>::new());
    assert_eq!(cli.foo, Foo(vec!["foo".into(), "bar".into()]));

    let cli = Cli::from_iter(vec!["", "--foo", "foo"]);
    assert_eq!(cli.foo, Foo(vec!["foo".into()]));

    let cli = Cli::from_iter(vec!["", "--foo", "foo,bar,baz"]);
    assert_eq!(cli.foo, Foo(vec!["foo".into(), "bar".into(), "baz".into()]));
}

【讨论】:

    【解决方案2】:

    我认为你不能这样做:虽然 StructOpt 在默认值方面有一些技巧,但我希望这仍然会以在 CLI 解析中注入默认值结束,就好像它已被显式提供一样,这意味着很可能无法提供多个默认值(尽管我肯定是错的)。

    您可能希望在应用程序级别处理此问题,例如解析 CLI 后,立即检查 foo 的元数,如果为空则更新它。

    【讨论】:

      猜你喜欢
      • 2020-05-04
      • 1970-01-01
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多