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"),
}
}
主要特性
- 使用
#[throws]
宏简化错误定义 - 自动错误类型转换
- 支持自定义错误类型
- 与标准库的
Result
类型无缝集成 - 简化错误传播语法
完整示例代码
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(())
}
优势
- 减少样板代码:自动生成错误类型的
Display
和Error
实现 - 清晰的错误传播:
try_!
宏使错误传播更直观 - 丰富的上下文:
with_context!
可以轻松添加上下文信息 - 类型安全:保持Rust强类型系统的优势
culpa-macros特别适合需要定义多种错误类型并需要清晰错误传播的中大型项目。