4

我试图弄清楚如何使用 Clap 从输入参数动态生成参数。

我试图用 Clap 模拟的是以下 python 代码:

parser = argparse.ArgumentParser()
parser.add_argument("-i", type=str, nargs="*")
(input_args, additional_args) = parser.parse_known_args()
for arg in input_args:
  parser.add_argument(f'--{arg}-bar', required=true, type=str)

additional_config = parser.parse_args(additional_args)

这样您就可以在命令中执行以下操作:

./foo.py -i foo bar baz --foo-bar foo --bar-bar bar --baz-bar bar

并从第一个参数动态生成附加参数。不确定是否可以在 Clap 中执行,但我认为这可能是因为自述文件说明您可以使用构建器模式动态生成参数 [1]。

所以这是我试图做到这一点的天真尝试。

use clap::{Arg, App};

fn main() {
  let mut app = App::new("foo")
               .arg(Arg::new("input")
               .short('i')
               .value_name("INPUT")
               .multiple(true)
               .required(true));
  let matches = app.get_matches_mut();
  let input: Vec<_> = matches.values_of("input").unwrap().collect()
  for i in input {
    app.arg(Arg::new(&*format!("{}-bar", i)).required(true))
  }
}

这显然不会让编译器在你的!format一生中尖叫,app.arg我最感兴趣的是解决我如何生成新的参数app,然后可以再次匹配。我对生锈还很陌生,所以很可能用 Clap 是不可能的。

[1] https://github.com/clap-rs/clap

4

1 回答 1

1

我认为这是可能的,因为自述文件指出您可以使用构建器模式来动态生成参数 [1]。

动态生成参数意味着,您可以.arg使用运行时值并且它会正常工作(也就是整个 CLI 不需要在编译时完全定义,这种区别在 Python 中不存在,因为一切都在运行时完成) .

当您传递未知参数然后重新解析它们时,您在这里所做的事情要复杂得多(并且专业且奇怪)。

现在首先,您实际上不能App在 clap 中重用:它的大多数方法(非常包括get_matches)获取self并因此“使用”应用程序并返回其他内容,原始应用程序或结果。虽然我猜你可以clone在你之前使用原始应用程序。get_matches

但我认为这在这里没有用:虽然我没有尝试过,但应该可以做你想做的事情TrailingVarArg:这会将所有尾随参数收集到一个位置 arg 切片中(你可能也需要AllowLeadingHyphen,然后你可以使用动态生成的参数创建第二个 App参数以解析该子集参数(get_matches_from将从迭代器而不是 env args 解析,这对于测试很有用......或对于这种确切的情况)。

于 2020-09-24T05:55:44.953 回答