2个稳定版本
| 1.1.0 | 2023年10月8日 |
|---|---|
| 1.0.0 | 2023年10月5日 |
2219 在 Rust模式
每月下载量21次
40KB
492 行
thistermination
thistermination是一个受thiserror启发的库,用于为错误枚举添加std::process::Termination特质。
[dependencies]
thistermination = "1.0"
编译器支持:需要rustc 1.56+
为什么实现Termination特质?
实现std::process::Termination和std::fmt::Debug特质的结构体或枚举可以被main函数返回,允许开发者打印程序退出的消息并设置退出码。
用法
要将std::process::Termination特质添加到枚举中,可以使用以下三个可能的derive宏之一:
-
#[derive(Termination)]:旨在与thiserror结合使用,此宏实现了std::process::Termination和std::fmt::Debug特质。默认的exit_code为libc::EXIT_FAILURE,除非显式使用exit_code和msg设置,否则Debug消息与Display消息相同。use thistermination::{Termination}; use thiserror::Error; #[derive(Error, Termination)] pub enum RequestError { #[error("request failed {0:?}")] RequestFailed(#[from] reqwest::Error), #[termination(msg("exiting wrong api key"))] #[error("wrong api key")] WrongAPIKey, #[termination(exit_code(3))] #[error("failed with status {0}")] RequestStatusError(u16), #[termination(exit_code(4), msg("exiting failed to load image {error:?}"))] #[error("failed to load image {error:?}")] ImageLoadError{#[from] error: image::ImageError}, } fn main() -> Result<(), RequestError> { Err(RequestError::WrongAPIKey) } -
#[derive(TerminationFull)]:此宏旨在不产生错误的情况下使用,实现了以下特质:std::process::Termination、std::fmt::Debug、std::fmt::Display和std::error::Error。默认的exit_code是libc::EXIT_FAILURE,而msg是必需的,并用于Display和Debug。use thistermination::{TerminationFull}; #[derive(TerminationFull)] pub enum RequestError { #[termination(exit_code(1), msg("request failed {0:?}"))] RequestFailed(#[from] reqwest::Error), #[termination(exit_code(2), msg("wrong api key"))] WrongAPIKey, #[termination(exit_code(3), msg("failed with status {0}"))] RequestStatusError(u16), #[termination(exit_code(4), msg("failed to load image {error:?}"))] ImageLoadError{#[from] error: image::ImageError}, } fn main() -> Result<(), RequestError> { Err(RequestError::WrongAPIKey) } -
#[derive(TerminationNoDebug)]:是最基本的变体,仅实现了std::process::Termination特质。如果没有提供exit_code,则默认为libc::EXIT_FAILURE。然而,对于枚举类型在main函数中返回,需要实现std::fmt::Debug特质,这必须手动实现或使用Debug宏。use thistermination::{TerminationNoDebug}; #[derive(TerminationNoDebug, Debug)] pub enum RequestError { #[termination(exit_code(1))] RequestFailed(reqwest::Error), WrongAPIKey, #[termination(exit_code(3))] RequestStatusError(u16), ImageLoadError{error: image::ImageError}, } fn main() -> Result<(), RequestError> { Err(RequestError::WrongAPIKey) }
详细信息
-
thistermination没有出现在您的公共API中;宏只是实现了各种特质。
-
这些宏可以为单元枚举、具有命名字段的枚举和枚举元组进行派生。
-
msg支持以格式字符串方式访问枚举的字段#[termination(msg("{var}"))]⟶write!("{}", self.var)#[termination(msg("{0}"))]⟶write!("{}", self.0)#[termination(msg("{var:?}"))]⟶write!("{:?}", self.var)#[termination(msg("{0:?}"))]⟶write!("{:?}", self.0)
您还可以为
msg指定额外的格式字符串参数。#[derive(TerminationFull)] pub enum RequestError { #[termination(exit_code(4), msg("failed to load image {0:?}"))] ImageLoadError(#[from] image::ImageError), } -
使用
#[from]将生成特定变体的std::convert::From实现。带有#[from]的变体不允许包含任何其他字段,并且只能与#[derive(TerminationFull)]一起使用。#[derive(TerminationFull)] pub enum CLIError { #[termination(exit_code(4), msg("Invalid argument {0}, expected < {}", i16::MAX))] InvalidArgument(u16), } -
您还可以通过将辅助属性
#[termination(...)]添加到枚举本身来更改exit_code和msg的默认值。#[derive(Error, Termination)] #[termination(exit_code(3), msg("Fatal Error"))] pub enum RequestError { #[error("request failed {0:?}")] RequestFailed(#[from] reqwest::Error), #[error("wrong api key")] WrongAPIKey, #[error("failed with status {0}")] RequestStatusError(u16), #[termination(exit_code(4), msg("exiting failed to load image {error:?}"))] #[error("failed to load image {error:?}")] ImageLoadError{#[from] error: image::ImageError}, }
与thiserror的比较
#[derive(TerminationFull)] 可以用来替代 thiserror,因为它提供了许多 thiserror 的基本功能。然而,它缺少一些功能,如 #[source]、#[backtrace]、自动检测堆栈跟踪的能力以及 #[error(transparent)]。如果需要这些功能中的任何一个,可以使用 thiserror 与 #[derive(Termination)] 结合使用。
依赖项
~2.4–4MB
~70K SLoC