使用docopt和Rust解析带有参数的命令行标志,类似于getopt

时间:2016-04-13 10:26:07

标签: rust docopt

我正在寻找一种方法来模拟C使用getopt的方式。我想使用docopt将以下C片段转换为Rust。我似乎无法将标志传递到命令行参数:

char in;
char* stringName;
while(( in = getopt( argc, argv, "a:b:c:d:e:")) != EOF) {
    switch(in) {
        case 'a':
            stringName = optarg;
            break;
     // ... and so on

然后我想跑

cargo run -a "hello" -b 3 ... and so on

到目前为止我写过:

extern crate rustc_serialize;
extern crate docopt;

use docopt::Docopt;

// Define a USAGE string
const USAGE: &'static str = "
Program.

Usage: [options] [<value1>] [options] [<value2>] [options] [<value3>] [options] [<value4>]

Options:
    -a, 
    -b, 
    -c,
    -d,  
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_value1: Option<String>,
    flag_a: bool,
    flag_b: bool,
    flag_c: bool,
    arg_value2: Option<String>,
    arg_value3: Option<String>,
    arg_value4: Option<String>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);
}

当我cargo run时,我

  

未知标志-a

1 个答案:

答案 0 :(得分:1)

这样的事情可能会让你非常接近:

const USAGE: &'static str = "
Program.

Usage: program [options]

Options:
    -a VALUE
    -b VALUE
    -c VALUE
    -d VALUE
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_a: Option<String>,
    flag_b: Option<i32>,
    flag_c: Option<String>,
    flag_d: Option<String>,
}

使用cargo run -- -a "hello" -b 3运行时(请参阅下面的注释),输出为:

Args { flag_a: Some("hello"), flag_b: Some(3), flag_c: None, flag_d: None }

然后,您可以在flag_a上进行模式匹配,以判断它是否已提供(从而获取值)。没有必要使用单独的布尔标志,在这种情况下Option更好。

作为Vladimir Matveev points out,当您通过cargo run执行程序时,必须将cargo的参数与程序的参数区分开来。执行此操作的大多数(所有?)程序使用特殊标志--执行此操作。这将程序之间的参数分开。您也可以在构建程序后直接运行该程序:

$ cargo build
$ ./target/debug/program_name -a "hello" -b 3