2个稳定版本
1.0.1 | 2023年8月1日 |
---|
#505 在 命令行界面
6KB
proxit — Rust中的UNIX风格错误信息
proxit
是一个超级简单的 Rust 库,通过为你实现 Termination
特性,让你能够以更少的样板代码拥有一致性的 UNIX 风格错误信息。
为什么?
所有 UNIX 命令行工具自开天辟地以来就以一种或另一种方式显示它们的错误信息
<utility name>: <error message>
有时候
Usage: <utility name> <utility arguments>
# or
usage: <utility name> <utility arguments>
例如
$ grep -fakeflags
grep: akeflags: No such file or directory
$ mandoc
bash: mandoc: command not found
$ doas
usage: doas [-Lns] [-C config] [-u user] command [args]
那么 Rust 团队的天才们是如何决定如何做的呢?让我们看看代码
impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {
fn report(self) -> ExitCode {
match self {
Ok(val) => val.report(),
Err(err) => {
io::attempt_print_to_stderr(format_args_nl!("Error: {err:?}"));
ExitCode::FAILURE
}
}
}
}
等等... 我看到的是这个吗?
… format_args_nl!("Error: {err:?}"));
兄弟。
Proxit 的工作原理
使用 proxit
非常简单
use proxit::MainResult;
fn main() -> MainResult<(), Error> {
work().into();
}
fn work() -> Result<(), Error> { /* … */ }
MainResult
仅仅是一个围绕实现了 Termination
的 Result<T, E>
的包装,其中 T
实现 Display
。实际上,T
将基本上总是 ()
,它实现了 Termination
。
当 main
函数返回时,如果 MainResult
内的 Result
是一个 Ok
变体,那么 T
的 report()
方法会被调用。否则,将 E
打印到标准错误(这就是为什么你需要实现 Display
),前面加上字符串 "{argv0}: "
,其中 argv0
是程序名。
如果你想打印使用字符串呢?嗯...因为越简单越好,只需调用 eprintln!()
和 process::exit()
。自己打印使用字符串也让你有灵活性来决定使用 GNU- 和 FreeBSD-style 使用字符串("Usage: {s}"
)和 OpenBSD-style 使用字符串("usage: {s}"
)。
use std::process;
use proxit::{self, MainResult, Usage};
fn main() -> MainResult<(), Error> {
work.into();
}
fn work() -> Result<(), Error> {
if usage_wrong() {
eprintln!("Usage: [-abc] required_arg");
process::exit(1);
}
}
附加说明
当使用此库的进程被启动时,调用 exec()
的父进程可能无法提供 argv[0]
中的程序名。在这种情况下,我们默认使用 Rust 风格的 "Error: {s}"
。