2 个版本
0.1.1 | 2023年9月14日 |
---|---|
0.1.0 | 2023年9月14日 |
#1087 在 Rust 模式
15KB
throwing
此crate实现了一个#[throws(...)]
宏,允许你轻松声明函数可以返回的错误。这将允许你穷举所有可能的错误。它受到Java中声明异常的启发。
#[throws(...)]
宏将自动生成一个可以表示所有已声明错误的枚举,为每个变体生成From<T>
实现,并将函数的返回类型更改为适当的Result<T, E>
。错误类型也将有Error
、Display
和Debug
的实现。
此外,它还可以为错误类型生成From<T>
实现,即从具有较少变体的错误类型转换为具有更多变体的错误类型。
安装
您可以使用以下命令将此crate添加到项目中
cargo add throwing
示例
从维基百科获取关于兔子的信息
use std::io::{self, stdout, Write};
use serde::Deserialize;
use throwing::throws;
#[derive(Clone, Deserialize)]
struct Summary {
extract: String,
}
#[throws(reqwest::Error | serde_json::Error)]
fn fetch_extract() -> String {
let url = "https://en.wikipedia.org/api/rest_v1/page/summary/Rabbit";
let response = reqwest::blocking::get(url)?;
let summary = response.text()?;
let summary: Summary = serde_json::from_str(&summary)?;
Ok(summary.extract)
}
#[throws(reqwest::Error | serde_json::Error | io::Error | break FetchExtractError)]
fn main() {
let extract = fetch_extract()?;
writeln!(stdout(), "{extract}")?;
Ok(())
}
从文件中读取整数并处理错误
use std::{fs, io, num::ParseIntError};
use throwing::throws;
#[throws(ParseIntError | io::Error)]
fn read_int_from_file(path: &str) -> i64 {
let content = fs::read_to_string(path)?;
let value = content.trim().parse()?;
Ok(value)
}
fn main() {
match read_int_from_file("file.txt") {
Ok(number) => println!("{number}"),
Err(ReadIntFromFileError::ParseIntError(e)) => eprintln!("Failed to parse int: {e}"),
Err(ReadIntFromFileError::IoError(e)) => eprintln!("Failed to read file: {e}"),
}
}
为自定义类型实现 FromStr
use std::{num::ParseIntError, str::FromStr};
use throwing::define_error;
pub struct Id(u64);
define_error!(pub type ParseIdError = ParseIntError);
impl FromStr for Id {
type Err = ParseIdError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let value = s.parse()?;
Ok(value)
}
}
通过 thiserror 添加带自定义错误的整数
您可以使用thiserror轻松创建简单的错误类型。
use std::{
io::{self, stdin, BufRead, Lines},
num::ParseIntError,
};
use thiserror::Error;
use throwing::throws;
#[derive(Debug, Error)]
#[error("unexpected end of file")]
struct EofError;
#[derive(Debug, Error)]
#[error("addition of {0} and {1} overflows")]
struct OverflowError(i32, i32);
fn add(a: i32, b: i32) -> Result<i32, OverflowError> {
a.checked_add(b).ok_or_else(|| OverflowError(a, b))
}
#[throws(io::Error | EofError)]
fn read_line(input: &mut Lines<impl BufRead>) -> String {
Ok(input.next().ok_or(EofError)??)
}
#[throws(io::Error | EofError | ParseIntError | OverflowError | break ReadLineError)]
fn main() {
let mut input = stdin().lock().lines();
let a = read_line(&mut input)?.parse()?;
let b = read_line(&mut input)?.parse()?;
let result = add(a, b)?;
println!("{result}");
Ok(())
}
依赖关系
~275–720KB
~17K SLoC