9个版本
0.3.4 | 2023年3月22日 |
---|---|
0.3.3 | 2023年3月22日 |
0.3.2 | 2023年1月17日 |
0.3.1 | 2022年12月3日 |
0.1.0 | 2022年11月28日 |
#624 in 命令行界面
每月57次下载
用于 chickensources
10KB
165 行
fncli
一个用于简化编写简单命令行应用程序的属性宏。
示例
#[fncli::cli]
fn main(a: i32, b: i32) {
println!("{}", a + b);
}
$ cargo run 1 2
3
$ cargo run 1
missing argument: `b: i32`
USAGE:
target/debug/examples/add <a: i32> <b: i32>
$ cargo run 1 2 3
too many arguments (expected 2)
USAGE:
target/debug/examples/add <a: i32> <b: i32>
$ cargo run 1 a
failed to parse argument: `b: i32`: ParseIntError { kind: InvalidDigit }
USAGE:
target/debug/examples/add <a: i32> <b: i32>
对于更完整的示例,请参阅时间流逝示例。
工作原理
fn main() {
let (a, b) = {
let mut args = std::env::args();
let cmd = args.next().expect("should have a command name");
let exit = |err: &str| -> ! {
eprintln!("{err}");
eprintln!();
eprintln!("USAGE:\n\t{cmd} <a: i32> <b: i32>");
std::process::exit(1)
};
let tuple = (
i32::from_str(
&args
.next()
.unwrap_or_else(|| exit("missing argument: `a: i32`")),
)
.unwrap_or_else(|e| exit(&format!("failed to parse argument `a: i32` ({e:?})"))),
i32::from_str(
&args
.next()
.unwrap_or_else(|| exit("missing argument: `b: i32`")),
)
.unwrap_or_else(|e| exit(&format!("failed to parse argument `b: i32` ({e:?})"))),
);
if args.next().is_some() {
exit("too many arguments (expected 2)");
}
tuple
};
{
println!("{}", a + b);
}
}
生成的代码非常简单,与手动编写的代码差别不大。
依赖项
~280–730KB
~17K SLoC