2个版本 (1个稳定版)
1.0.0 | 2020年11月20日 |
---|---|
0.1.0 | 2020年11月12日 |
#20 在 #error-chain
每月29次下载
在embedded-error-chain中使用
32KB
660 行
嵌入式错误链
嵌入式设备易于处理错误(无需liballoc
和no_std
)。
错误由错误码表示,来自实现ErrorCategory
特质(存在一个派生宏)的枚举,该特质用于按错误码进行自定义调试打印等。每个错误码可以有一个值从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
lib.rs
:
嵌入式错误链的派生宏。
依赖项
~1.5MB
~35K SLoC