2个版本 (1个稳定版)

1.0.0 2020年11月20日
0.1.0 2020年11月12日

#20#error-chain

每月29次下载
embedded-error-chain中使用

MIT许可

32KB
660

嵌入式错误链

build crates.io docs

嵌入式设备易于处理错误(无需liballocno_std)。

错误由错误码表示,来自实现ErrorCategory特质(存在一个派生宏)的枚举,该特质用于按错误码进行自定义调试打印等。每个错误码可以有一个值从015(4位),并且你可以将错误与最多四个不同分类的错误码链接。

Error类型封装了一个错误码和错误链,它的大小仅为单个u32。还有一个无类型的DynError类型,与Error不同,它没有当前错误码的类型参数。它的大小是一个u32 + 指针(usize),可以用于将不同分类的源错误传递给调用者。

这个库受到了如error-chainanyhowthiserror等库的启发,尽管它被设计在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