7 个版本
0.1.6 | 2021年6月26日 |
---|---|
0.1.5 | 2021年6月26日 |
0.1.4 | 2021年4月18日 |
#516 in 命令行界面
26 个月下载量
79KB
1.5K SLoC
Parsnip
Rust 的小型 Argparser
// ./prog --arg param1 param2 -a
fn main() {
let args = args! {
// define all your args here
args: vec![arg! {
name: "arg",
short: Some("a"),
}, arg! {
name: "arg2",
long: Some("arg2"),
num_values: NumValues::Between(1, 3),
}],
// subcommands (e.g git add)
subcommands: vec![args! {}],
// optional, by default parsing will return a "Results" object
handler: |results| { return results.args.get("arg2"); }
};
let results = args.parse(std::env::args());
}
设置
将库添加到您的 Cargo.toml
.
[dependencies]
argparsnip = "0.1.5"
功能
- 自动生成的帮助/版本命令
- 可以重写
- [subcommand]* 帮助 & [subcommand]* 版本命令也会生成
- 名称/版本/关于参数默认使用 Cargo.toml 中的
CARGO_PKG_NAME/CARGO_PKG_VERSION/CARGO_PKG_DESCRIPTION
变量
- 参数
- 支持短
-h
和--help
语法 - 默认支持 Unicode
- 支持返回(作为 vec)或因未知参数而失败
- 标志
- 支持组合(例如
-rli
等同于-r -l -i
) - 支持重复,例如
-vvv -v
将被视为出现 4 次的同一标志v
- 支持组合(例如
- 带有值
- 支持对参数值的数量进行限制,例如精确地有一个值,有两个到四个值,或任何数量的值。例如
-v foo bar
- 支持通过 TryInto 特性将值限制为特定的 原始 类型(任何、bool、i32、i64、f32、f64、String)
- 支持额外的自定义验证(因此您可以编写自己的 sum 类型限制,例如)
- 支持默认值
- 支持对参数值的数量进行限制,例如精确地有一个值,有两个到四个值,或任何数量的值。例如
- 组合
- 可以将解析配置为如果缺少任何必需的参数则失败
- 支持要求一组参数中的至少一个(例如 A || B || C)
- 支持要求一组中的所有参数(例如 A && B && C)
- 支持反转集合(例如 !(A && B))
- 支持要求多个集合中的任意或所有(例如 (A && B) || (A && C))。这也可以被否定
- 位置参数
- 支持 Unix
--
,即foo -- -a -b -c
将接收位置参数 ["-a", "-b", "-c"] - 将所有不以
-
或--
开头的参数视为位置参数。
- 支持 Unix
- 支持短
- 子命令
- 例如 cargo run 与 cargo test(run/test 是子命令)
- 子命令可以有它们自己的子命令和参数
- 为每个子命令生成单独的帮助/版本命令
- 可选回调支持
- 而不是返回一个包含 argparsing 结果的结果对象,可以为每个命令/子命令提供一个处理函数 fn(Results) -> T(在使用 serde 时不受支持)。
- no_std 支持
- 禁用默认功能以启用 no_std
parsnip= {版本= "x",默认-功能= false }
- serde 支持
parsnip= {版本= "x",功能= ["derive"] }
- 使用任何格式(serde_json、toml 等)的 serde 解析器编写您的参数模式(参见 derive-test 以获取示例)
- 其他可选功能
- debug - 启用有关参数解析的日志记录信息
- macros - 默认启用,我们提供了一些实用宏,以避免在各个地方编写 ..Default::default()
用法
以下是一些快速常见情况。有关更多示例,请参阅 lib.rs
中的测试
文档
https://docs.rs/argparsnip/0.1.5/argparsnip/
示例
最小标志示例
// ./prog --arg
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
short: Some("a"),
}],
};
let results = args.parse(std::env::args());
assert_eq!(1, results.flags("arg"));
}
检查是否给出了标志
// ./prog --arg
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
short: Some("a"),
about: "a flag",
long: Some("arg"),
required: true,
}],
};
let results = args.parse(std::env::args());
assert_eq!(1, results.flags("arg"));
}
获取参数的值
// ./prog -a 1
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
short: Some("a"),
default: Some(|| { Value::From(2) }),
value_type: Type::Int,
num_values: NumValues::Fixed(1),
}],
};
let results = args.parse(std::env::args());
assert_eq!(1, results.params.get("arg")?.try_into());
}
验证参数
// ./prog -a 1 2
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
short: Some("a"),
value_type: Type::Int,
num_values: NumValues::AtLeast(1),
validation: |val| {
let val: &i32 = v.try_into().unwrap();
if 2 >= *val {
Ok(())
} else {
Err("failed validation")
}
}
}],
};
let results = args.parse(std::env::args());
assert_eq!(vec![1, 2], results.params.get("arg")?.try_into());
}
使用子命令
// ./prog sub --arg
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
long: Some("arg"),
num_values: NumValues::None,
}],
subcommands: vec![args! {
name: "sub",
path: Some("main/sub"),
args: vec![arg! {
name: "arg",
long: Some("arg"),
num_values: NumValues::None,
}],
}],
};
let results = args.parse(std::env::args());
// this is the unique identifier for the subcommand
assert_eq!("main/sub", results.path);
assert_eq!(1, results.flags["arg"]);
}
过滤器
// only supports combinations (--arg && --arg2) or (--arg && --arg3)
// will fail if --arg or --arg2 or --arg3 are passed on their own
fn main() {
let args = args! {
args: vec![arg! {
name: "arg",
long: Some("arg"),
num_values: NumValues::None,
}, arg! {
name: "arg2",
long: Some("arg2"),
num_values: NumValues::None,
}, arg! {
name: "arg3",
long: Some("arg3"),
num_values: NumValues::None,
}],
filters: Filters {
filters: vec![Filter {
filter_type: FilterType::All,
inverse: false,
args: vec!["arg", "arg2"],
}, Filter {
filter_type: FilterType::All,
inverse: false,
args: vec!["arg", "arg3"],
}],
..Default::default()
},
// this flag means we will fail if we see the same value multiple times
disable_overrides: true,
};
let results = args.parse(std::env::args());
}
开发
待办事项
- 基准测试
- 更多测试
- 功能
- Bash/Zsh 完成功能
- 支持禁用位置参数
- 支持更新重复项,例如 --arg Foo --arg Bar 应该给出 {"arg": ["Foo", "Bar"]}
- 我的设计可能不是迭代器友好,请尝试使用计数器代替
依赖项
~0.5–1MB
~15K SLoC