3 个版本 (重大更改)
0.3.0 | 2023年4月19日 |
---|---|
0.2.0 | 2023年3月26日 |
0.1.0 | 2023年2月7日 |
#444 在 Rust 模式
每月下载量 630
在 4 个crate中使用
82KB
1K SLoC
Argp 是一个基于 Derive 的参数解析器,优化代码大小和灵活性。
该库的公共 API 主要包括 FromArgs
derive 和 parse_args_or_exit
函数,可用于从当前程序的命令行参数生成顶级的 FromArgs
类型。
功能
-
零运行时依赖。
-
小尺寸开销 - ~40 kiB [1],这是 比 clap 或 clap_derive 少 10 倍!有关更多详细信息,请参阅 argparse-rosetta-rs。
-
基于 Derive 的 API - 您定义用于解析值的结构和枚举,使用属性来指定它们应该如何被解析,过程宏将在编译时生成解析器。
-
上下文敏感解析。
-
支持子命令。
-
带有 Markdown 支持和基于终端宽度的动态包装的帮助信息生成器。
起源
Argp 最初是从 argh 分支出来的,以使其更无偏见、更 UNIX 风格和更灵活。
与 argh 的显著变化
-
支持全局选项(即顶层定义的选项可以在子命令中使用)。
-
支持组合短选项(例如,
-ab
被解析为-a -b
,-an 5
被解析为-a -n 5
)。 -
支持非 UTF-8 参数 (OsStr)。
-
from_str_fn
属性也可以包含函数路径,而不仅仅是单个标识符,并且可以返回任何实现了ToString
的Err
类型。 -
描述不需要以小写字母开头。
-
帮助信息根据终端宽度动态包装(在 Unix 系统上)。
-
帮助信息中描述的缩进根据所有元素的宽度动态计算。
-
即使是在位置参数上,也可以使用
arg_name
属性来自定义在帮助信息中显示参数的方式。 -
错误使用枚举而不是字符串表示,生成帮助信息的所需信息以部分结构化的形式存储在结构体中;这为消息的定制打开了大门。
-
专门的
example
、note
和error_code
属性被单个footer
属性替换——您可以用它来做任何您想做的事情。 -
在用法字符串中的位置参数在选项和开关之后显示,并在选项的描述中显示
<arg_name>
。 -
允许在
-h, --help
开关之后使用尾部选项,但仅限于在help
子命令之后不允许。 -
将
from_env
函数重命名为parse_args_or_exit
,将cargo_from_env
重命名为cargo_parse_args_or_exit
。 -
已移除
redact_arg_values
(如果您偶然需要它,请在问题中告诉我)。
基本示例
use argp::FromArgs;
/// Reach new heights.
#[derive(FromArgs)]
struct GoUp {
/// Whether or not to jump.
#[argp(switch, short = 'j')]
jump: bool,
/// How high to go.
#[argp(option, arg_name = "meters")]
height: usize,
/// An optional nickname for the pilot.
#[argp(option, arg_name = "name")]
pilot_nickname: Option<String>,
}
fn main() {
let up: GoUp = argp::parse_args_or_exit(argp::DEFAULT);
}
./some_bin --help
将输出以下内容
Usage: cmdname [-j] --height <meters> [--pilot-nickname <name>]
Reach new heights.
Options:
-j, --jump Whether or not to jump.
--height <meters> How high to go.
--pilot-nickname <name> An optional nickname for the pilot.
-h, --help Show this help message and exit.
生成的程序可以以以下任何方式使用
-
./some_bin --height 5
-
./some_bin -j --height 5
-
./some_bin --jump --height 5 --pilot-nicknameWes
开关,如jump
,是可选的,如果提供,则将其设置为true。
选项,如height
和pilot_nickname
,可以是必需的、可选的或重复的,具体取决于它们是否包含在Option
或Vec
中。可以使用#[argp(default = "<your_code_here>")]
属性提供默认值,在这种情况下,选项被视为可选的。
use argp::FromArgs;
fn default_height() -> usize {
5
}
/// Reach new heights.
#[derive(FromArgs)]
struct GoUp {
/// An optional nickname for the pilot.
#[argp(option)]
pilot_nickname: Option<String>,
/// An optional height.
#[argp(option, default = "default_height()")]
height: usize,
/// An optional direction which is "up" by default.
#[argp(option, default = "String::from(\"only up\")")]
direction: String,
}
fn main() {
let up: GoUp = argp::parse_args_or_exit(argp::DEFAULT);
}
只要自定义选项类型实现了FromArgValue
特质(对于大多数在std中实现了FromStr
特质的标准类型已经实现),就可以反序列化自定义选项类型。如果需要更定制化的解析,您可以使用from_str_fn
属性提供一个自定义的fn(&str) → Result<T, E>
,或使用from_os_str_fn
属性提供一个自定义的fn(&OsStr) → Result<T, E>
,其中E
实现了ToString
use argp::FromArgs;
use std::ffi::OsStr;
use std::path::PathBuf;
/// Goofy thing.
#[derive(FromArgs)]
struct FineStruct {
/// Always five.
#[argp(option, from_str_fn(always_five))]
five: usize,
/// File path.
#[argp(option, from_os_str_fn(convert_path))]
path: PathBuf,
}
fn always_five(_value: &str) -> Result<usize, String> {
Ok(5)
}
fn convert_path(value: &OsStr) -> Result<PathBuf, String> {
Ok(PathBuf::from("/tmp").join(value))
}
可以使用#[argp(positional)]
声明位置参数。这些参数将按照结构体中声明的顺序解析
use argp::FromArgs;
/// A command with positional arguments.
#[derive(FromArgs, PartialEq, Debug)]
struct WithPositional {
#[argp(positional)]
first: String,
}
最后一个位置参数可以包含默认值,或者用Option
或Vec
包裹,以表示可选或重复的位置参数。
也支持子命令。要使用子命令,需要为每个子命令声明一个单独的FromArgs
类型,以及一个遍历每个命令的枚举。
use argp::FromArgs;
/// Top-level command.
#[derive(FromArgs, PartialEq, Debug)]
struct TopLevel {
/// Be verbose.
#[argp(switch, short = 'v', global)]
verbose: bool,
#[argp(subcommand)]
nested: MySubCommandEnum,
}
#[derive(FromArgs, PartialEq, Debug)]
#[argp(subcommand)]
enum MySubCommandEnum {
One(SubCommandOne),
Two(SubCommandTwo),
}
/// First subcommand.
#[derive(FromArgs, PartialEq, Debug)]
#[argp(subcommand, name = "one")]
struct SubCommandOne {
/// How many x.
#[argp(option)]
x: usize,
}
/// Second subcommand.
#[derive(FromArgs, PartialEq, Debug)]
#[argp(subcommand, name = "two")]
struct SubCommandTwo {
/// Whether to fooey.
#[argp(switch)]
fooey: bool,
}
有关更多信息,请参阅argp 文档。
如何调试 argp
的展开 derive 宏
可以使用cargo-expand 包调试argp::FromArgs
derive 宏。
在examples/simple_example.rs
中展开 derive 宏
请参阅argp/examples/simple_example.rs,以了解我们想要展开的示例结构体。
首先,运行cargo install cargo-expand
安装cargo-expand
。注意,这需要 Rust 的夜间构建。
安装完成后,在 argp
包中运行cargo expand
,你将可以看到展开后的代码。
许可证
本项目受BSD-3-Clause 许可证许可。有关许可证的全文,请参阅LICENSE文件。
- 在带有
strip = true
和panic = "abort"
的发布构建中进行了测量。确切的大小取决于多个因素,包括选项和子命令的数量。
依赖关系
~3MB
~59K SLoC