2 个版本 (1 个稳定版本)
1.0.0 | 2020 年 11 月 20 日 |
---|---|
0.1.1 | 2020 年 11 月 13 日 |
0.1.0 |
|
在 嵌入式开发 中排名 1944
63KB
726 行(不包括注释)
embedded-error-chain
为嵌入式设备提供轻松的错误处理(无 liballoc
和 no_std
)。
错误通过错误代码表示,并来自实现 ErrorCategory
特性的枚举(存在一个 derive 宏),用于按错误代码进行自定义调试打印等。每个错误代码可以有一个从 0
到 15
(4 位)的值,并且您可以使用多达四个不同类别的不同错误代码来链接一个错误。
Error
类型封装了一个错误代码和错误链,大小仅为单个 u32
。还有一个无类型的 DynError
类型,与 Error
不同,它没有当前错误代码的类型参数。其大小为 u32
+ 指针 (usize
),可用于将不同类别的源错误传递给调用者。
这个库受到了例如 error-chain、anyhow 和 thiserror 等库的启发,但它被制作成在 no_std
和 无 liballoc
环境中工作,内存开销非常小。
示例
use embedded_error_chain::prelude::*;
#[derive(Clone, Copy, ErrorCategory)]
#[repr(u8)]
enum SpiError {
BusError,
// ...
}
static LAST_GYRO_ACC_READOUT: usize = 200;
#[derive(Clone, Copy, ErrorCategory)]
#[error_category(links(SpiError))]
#[repr(u8)]
enum GyroAccError {
InitFailed,
#[error("{variant} (readout={})", LAST_GYRO_ACC_READOUT)]
ReadoutFailed,
/// Value must be in range [0, 256)
#[error("{variant}: {summary}")]
InvalidValue,
}
fn main() {
if let Err(err) = calibrate() {
// log the error
println!("{:?}", err);
// ...
}
let readout = match gyro_acc_readout() {
Ok(val) => val,
Err(err) => {
if let Some(spi_error) = err.code_of_category::<SpiError>() {
// try to fix it
0
}
else {
panic!("unfixable spi error");
}
}
};
}
fn spi_init() -> Result<(), SpiError> {
Err(SpiError::BusError)
}
fn gyro_acc_init() -> Result<(), Error<GyroAccError>> {
spi_init().chain_err(GyroAccError::InitFailed)?;
Ok(())
}
fn gyro_acc_readout() -> Result<u32, Error<GyroAccError>> {
Err(SpiError::BusError.chain(GyroAccError::InvalidValue))
}
fn calibrate() -> Result<(), DynError> {
gyro_acc_init()?;
// other stuff...
Ok(())
}
许可证:MIT
依赖项
~1.5MB
~35K SLoC