3 个版本 (1 个稳定版本)

使用旧 Rust 2015

1.0.0 2015年6月29日
0.2.0 2015年4月30日
0.1.0 2015年4月28日

#366命令行界面

Download history 10/week @ 2024-02-19 45/week @ 2024-02-26

每月 55 次下载
2 个库中使用 (通过 tomllib)

LGPL-3.0+

27KB
493 代码行

Pirate 构建状态

使用 Rust 编写的命令行参数解析器。

概要

大多数提供命令行界面的程序都使用专用库来简化这个过程,例如 GNU 项目中的 getopt 库。Rust 团队提供自己的替代方案,getoptions,该方案值得获得“最具原始命名项目”奖项。

认真地说,getoptions 是一个出色的库,为开发者提供了创建和与命令行参数交互所需的所有功能。然而,功能越多,复杂性就越大。getoptions 虽然使用简单,但相当冗长。开发者必须反复调用不同的函数才能将不同的命令行选项添加到他们的程序中。虽然唯一的受害者是开发者的手腕,因为腕管综合症,但我认为还有更好的方法来做这件事。

于是出现了海盗(应该完全取代 getoptions,获得“最具原始命名项目”奖项)。

安装

将以下内容添加到您的项目的 Cargo.toml 文件中:

[dependencies]
pirate = "1.0.0"

并添加以下内容到您的库根目录:

extern crate pirate;

用法

使用海盗很简单。首先,创建一个定义了程序接受的全部有效选项的向量

let options = vec![
    "a/addend#The right side of the addition equation; default=1:",
    "#Required Arguments",
    ":augend#The left side of an addition equation"
];

选项定义在非常特定的格式中

  • 具有关联参数的选项后面必须跟一个冒号(:)。冒号必须是选项的最后一个字符(见上面示例)。
  • 长格式选项以一个前置斜杠(/)表示。选项可以同时有短格式和长格式。只有长格式的选项仍需要前置斜杠,例如 "/addend"
  • 必需的程序参数必须在选项前加上一个前置冒号(:),例如 ":augend"
  • 选项描述通过前置的井号(#)标识。描述是可选的,用于显示有关选项的有用信息(通常在传递 --help 标志时显示程序的使用信息)。只有描述(即没有短或长形式名称)的选项称为“组”,用于在显示使用时将选项分组。

接下来,创建一个 Vars 结构体,该结构体负责跟踪所有选项,以及为程序定义的程序名称

let vars: Vars = match pirate::vars("program-name", &options) {
    Ok(v) => v,
    Err(why) => panic!("Error: {}", why)
}

接下来,调用 pirate::matches() 函数,传入程序环境参数的向量,以及之前定义的 Vars 结构体的可变引用

let matches: Matches = match pirate::matches(env::args().collect(),
        &mut vars) {
    Ok(m) => m,
    Err(why) => {
        println!("Error: {}", why);
        pirate::usage(&vars);
        return;
    }
}

Matches 仅仅是 HashMap<String, String> 的类型别名。所有使类型更容易使用的自定义方法都是由 Match 特性定义的。

最后,检查传递给程序的哪些参数。

// Returns a reference to the given arg, or None if not found
fn get(arg: &str) -> Option<&String>;

// Returns true if the match exists, false if not
fn has_match(arg: &str) -> bool;

// An iterator over all matches found
fn keys() -> Keys<String, String>;

在使用 get() 函数时需要注意的事情:默认情况下,pirate::matches() 函数将 opt 的长形式名称作为键存储,默认情况下,如果存在长形式,则使用长形式;否则使用短形式。因此,如果您定义了一个同时具有短和长形式名称的 opt,在查询时,应传递长形式作为参数。例如

let options = vec!["l/long#An example opt"];
let vars = pirate::vars("program-name", &options);
let matches = pirate::matches(&env::args().collect(),
    &mut vars).unwrap();

let short = matches.get("l").unwrap(); // Error! This won't work!
let long = matches.get("long").unwrap(); // Success!

// Usage: program-name -l

如前一个示例所示,如果您想显示程序的使用数据,只需调用 pirate::usage() 函数,将您的 Vars 结构体的引用作为参数传递。例如 pirate::usage(&vars)

示例

这是一个简单示例,说明如何使用 pirate 的一般方法

extern crate pirate;

use pirate::{Matches, Match, matches, usage, vars};

fn main() {
    let env_args: Vec<String> = vec![
        String::from("test"),
        String::from("-a"), String::from("2"),
        String::from("3")
    ];
    let options = vec![
        "a/addend#The right side of the addition equation; default=1:",
        "#Required Arguments",
        ":augend#The left side of an addition equation"
    ];
    let mut vars = vars("test", &options).unwrap();
    
    let matches: Matches = match matches(&env_args, &mut vars) {
        Ok(m) => m,
        Err(why) => {
            println!("Error: {}", why);
            usage(&vars);
            return;
        }
    };
    
    if matches.has_match("help") {
        usage(&vars);
        return;
    }
    
    let augend: i32 = matches.get("augend")
                        .unwrap()
                        .parse::<i32>()
                        .unwrap();

    let addend: i32 = match matches.get("addend") {
        Some(a) => a.parse::<i32>().unwrap(),
        None => 1
    };
    
    let sum = augend + addend;
    
    println!("{} + {} = {}", augend, addend, sum);
}

许可证

Pirate 使用 GNU Lesser General Public License, v3 许可。

无运行时依赖