This crate implements a #[throws(...)]
macro that allows you to easily
declare what errors a function can return.
This will allow you to exhaustively match on all possible errors.
It is inspired by declared exceptions in Java.
The #[throws(...)]
macro will automatically generate an enum that can
represent all declared errors, generate From<T>
implementations for
each variant, and change the return type of the function to
an appropriate Result<T, E>
.
The error type will also have implementations of Error
, Display
and Debug
.
Additionally, it can generate From<T>
implementation for upcasting errors,
that is converting an error type with fewer variants to one with more variants.
You can add this crate to your project with:
sh
cargo add throwing
```rust use std::io::{self, stdout, Write}; use serde::Deserialize; use throwing::throws;
struct Summary { extract: String, }
fn fetchextract() -> String { let url = "https://en.wikipedia.org/api/restv1/page/summary/Rabbit"; let response = reqwest::blocking::get(url)?;
let summary = response.text()?;
let summary: Summary = serde_json::from_str(&summary)?;
Ok(summary.extract)
}
fn main() { let extract = fetch_extract()?; writeln!(stdout(), "{extract}")?;
Ok(())
} ```
```rust use std::{fs, io, num::ParseIntError};
use throwing::throws;
fn readintfromfile(path: &str) -> i64 { let content = fs::readto_string(path)?; let value = content.trim().parse()?; Ok(value) }
fn main() { match readintfrom_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}"), } } ```
```rust 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)
}
} ```
You can use thiserror to easily make simple error types.
```rust use std::{ io::{self, stdin, BufRead, Lines}, num::ParseIntError, };
use thiserror::Error; use throwing::throws;
struct EofError;
struct OverflowError(i32, i32);
fn add(a: i32, b: i32) -> Result
fn readline(input: &mut Lines
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(())
} ```