【问题标题】:Dynamically generating arguments Clap动态生成参数 Clap
【发布时间】:2021-01-10 03:42:45
【问题描述】:

我试图弄清楚如何使用 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 中进行,但我认为这可能是因为 Readme 声明您可以使用构建器模式动态生成参数[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 生成新参数,然后可以再次匹配。我对 rust 很陌生,所以 Clap 很可能无法做到这一点。

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

【问题讨论】:

标签: rust command-line-arguments clap


【解决方案1】:

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

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

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

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

但我认为这在这里没有用:虽然我没有尝试过,但应该可以使用TrailingVarArg 做你想做的事:这会将所有尾随参数收集到一个位置 arg 切片中 (you will probably need AllowLeadingHyphen as well),然后你可以创建一个 second App 动态生成的参数,以解析参数的子集(get_matches_from will parse from an iterator rather than the env args,这对于测试很有用......或者对于这种确切的情况)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多