2个稳定版本

1.0.1 2023年8月1日

#505命令行界面

0BSD 许可证

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 仅仅是一个围绕实现了 TerminationResult<T, E> 的包装,其中 T 实现 Display。实际上,T 将基本上总是 (),它实现了 Termination

main 函数返回时,如果 MainResult 内的 Result 是一个 Ok 变体,那么 Treport() 方法会被调用。否则,将 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}"

无运行时依赖