Rust错误处理宏库culpa-macros的使用,culpa-macros提供高效错误定义与传播的宏工具

Rust错误处理宏库culpa-macros的使用

culpa-macros是一个提供高效错误定义与传播的宏工具库,它简化了Rust中错误处理的定义和传播过程。

安装

在项目目录中运行以下Cargo命令:

cargo add culpa-macros

或者在Cargo.toml中添加:

culpa-macros = "1.0.2"

使用示例

以下是culpa-macros库的完整使用示例:

use culpa_macros::throws;

// 使用throws宏定义一个可能返回错误的函数
#[throws(i32)]
fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        // 自动转换为错误类型
        return Err("Division by zero");
    }
    a / b
}

// 定义自定义错误类型
#[derive(Debug)]
enum MyError {
    DivisionByZero,
    NegativeNumber,
}

// 使用自定义错误类型
#[throws(MyError)]
fn safe_divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        return Err(MyError::DivisionByZero);
    }
    if a < 0 || b < 0 {
        return Err(MyError::NegativeNumber);
    }
    a / b
}

fn main() {
    // 使用?操作符传播错误
    #[throws(i32)]
    fn calculate() -> i32 {
        let x = divide(10, 2)?;
        let y = divide(x, 5)?;
        y
    }
    
    match calculate() {
        Ok(result) => println!("Result: {}", result),
        Err(e) => println!("Error: {}", e),
    }
    
    match safe_divide(10, -5) {
        Ok(result) => println!("Result: {}", result),
        Err(MyError::DivisionByZero) => println!("Cannot divide by zero"),
        Err(MyError::NegativeNumber) => println!("Negative numbers not allowed"),
    }
}

主要特性

  1. 使用#[throws]宏简化错误定义
  2. 自动错误类型转换
  3. 支持自定义错误类型
  4. 与标准库的Result类型无缝集成
  5. 简化错误传播语法

完整示例代码

use culpa_macros::throws;
use std::fmt;

// 自定义错误类型
#[derive(Debug)]
enum MathError {
    DivisionByZero,
    NegativeNumber,
    Overflow,
}

// 为自定义错误实现Display trait
impl fmt::Display for MathError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            MathError::DivisionByZero => write!(f, "Division by zero error"),
            MathError::NegativeNumber => write!(f, "Negative number not allowed"),
            MathError::Overflow => write!(f, "Arithmetic overflow"),
        }
    }
}

// 使用culpa-macros定义数学运算函数
#[throws(MathError)]
fn math_operations(a: i32, b: i32) -> i32 {
    // 检查负数
    if a < 0 || b < 0 {
        return Err(MathError::NegativeNumber);
    }
    
    // 检查除以零
    if b == 0 {
        return Err(MathError::DivisionByZero);
    }
    
    // 检查溢出
    let result = a.checked_div(b).ok_or(MathError::Overflow)?;
    
    // 返回结果
    result
}

fn main() {
    // 测试各种情况
    let test_cases = vec![
        (10, 2),
        (10, 0),
        (-5, 3),
        (i32::MAX, 0),
    ];
    
    for (a, b) in test_cases {
        match math_operations(a, b) {
            Ok(result) => println!("{} / {} = {}", a, b, result),
            Err(e) => println!("Error for {} / {}: {}", a, b, e),
        }
    }
    
    // 嵌套使用示例
    #[throws(MathError)]
    fn nested_calculation(x: i32, y: i32, z: i32) -> i32 {
        let temp = math_operations(x, y)?;
        math_operations(temp, z)?
    }
    
    println!("\nNested calculation example:");
    match nested_calculation(20, 5, 2) {
        Ok(res) => println!("Result: {}", res),
        Err(e) => println!("Error: {}", e),
    }
}

许可证

culpa-macros采用MIT或Apache-2.0双许可证。


1 回复

culpa-macros - Rust错误处理宏库

culpa-macros是一个用于简化Rust错误处理的宏库,它提供了一套高效的宏工具来定义和传播错误。

主要特性

  • 简化错误类型定义
  • 自动实现std::error::Error trait
  • 提供便捷的错误传播机制
  • 支持错误上下文添加

安装

在Cargo.toml中添加依赖:

[dependencies]
culpa-macros = "0.1"

使用方法

1. 定义错误类型

use culpa_macros::throws;

#[throws]
#[derive(Debug)]
pub enum MyError {
    #[error("IO error occurred: {0}")]
    IoError(#[from] std::io::Error),
    
    #[error("Invalid input: {0}")]
    InvalidInput(String),
    
    #[error("Network timeout")]
    Timeout,
}

2. 使用try_宏传播错误

use culpa_macros::try_;

fn read_file(path: &str) -> Result<String, MyError> {
    let content = try_!(std::fs::read_to_string(path));
    Ok(content)
}

3. 添加错误上下文

use culpa_macros::{try_, with_context};

fn process_file(path: &str) -> Result<(), MyError> {
    let content = try_!(
        std::fs::read_to_string(path),
        with_context!("Failed to read file: {}", path)
    );
    
    // 处理内容...
    Ok(())
}

4. 自定义错误生成

use culpa_macros::throw;

fn validate_input(input: &str) -> Result<(), MyError> {
    if input.is_empty() {
        throw!(MyError::InvalidInput("Input cannot be empty".to_string()));
    }
    Ok(())
}

完整示例

use culpa_macros::{throws, try_, with_context, throw};

#[throws]
#[derive(Debug)]
pub enum AppError {
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
    
    #[error("Validation failed: {0}")]
    Validation(String),
    
    #[error("Processing error")]
    Processing,
}

fn read_config() -> Result<String, AppError> {
    let path = "config.toml";
    let content = try_!(
        std::fs::read_to_string(path),
        with_context!("Failed to read config file at {}", path)
    );
    Ok(content)
}

fn validate(content: &str) -> Result<(), AppError> {
    if content.len() > 1024 {
        throw!(AppError::Validation("Config too large".to_string()));
    }
    Ok(())
}

fn main() -> Result<(), AppError> {
    let config = read_config()?;
    validate(&config)?;
    
    println!("Config loaded successfully");
    Ok(())
}

优势

  1. 减少样板代码:自动生成错误类型的DisplayError实现
  2. 清晰的错误传播try_!宏使错误传播更直观
  3. 丰富的上下文with_context!可以轻松添加上下文信息
  4. 类型安全:保持Rust强类型系统的优势

culpa-macros特别适合需要定义多种错误类型并需要清晰错误传播的中大型项目。

回到顶部