StructOpt - 如何为 Vec 提供默认值?
StructOpt - how to provide a default value for a Vec?
我正在寻找一种默认情况下使用多个项目初始化 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"]
?
我不认为你能做到这一点:虽然 StructOpt 有一些关于默认值的技巧,但我希望这仍然以在 CLI 解析中注入默认值而结束,就好像它已被显式提供一样,这意味着可能无法提供多个默认值(尽管我肯定是错的)。
您可能想在 application-level 处处理此问题,例如解析 CLI 后,立即检查 foo
的数量,如果为空则更新它。
我听从了 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()]));
}
我正在寻找一种默认情况下使用多个项目初始化 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"]
?
我不认为你能做到这一点:虽然 StructOpt 有一些关于默认值的技巧,但我希望这仍然以在 CLI 解析中注入默认值而结束,就好像它已被显式提供一样,这意味着可能无法提供多个默认值(尽管我肯定是错的)。
您可能想在 application-level 处处理此问题,例如解析 CLI 后,立即检查 foo
的数量,如果为空则更新它。
我听从了 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()]));
}