ez 0.0.6

A collection of easy-to-use, beginner-friendly utilities for Rust.
Documentation
use ez::throws;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    for n in 0..10 {
        let x = fallible_dynamic(n)?;
        let y = fallible_concrete(n)?;
        println!("{x} {y}");
    }

    Ok(())
}

// throws a dynamic (eyre::Report) error
#[throws]
fn fallible_dynamic(n: i32) -> i32 {
    match n {
        // implicit return
        0 => 1,
        1 => {
            // explicit return
            return 2;
        },
        2 => {
            #[allow(clippy::all)]
            [3, 4, 5]
                .iter()
                .map(|x| {
                    // doesn't touch return in a closure
                    return x * 2;
                })
                .collect::<Vec<_>>()
                .last()
                .unwrap()
                .clone()
        },
        3 => {
            #[allow(clippy::all)]
            fn double(x: i32) -> i32 {
                let double = x * 2;
                // doesn't touch return in a nested function
                return double;
            }
            double(4)
        },
        4 => {
            // errors can be propagated with ?
            "what".parse()?
        },
        5 => {
            // error messages can be returned with throw!;
            throw!("this is an error");
        },
        _ => {
            // or specific error types
            let e: std::num::ParseIntError = "what".parse::<i32>().unwrap_err();
            throw!(e)
        },
    }
}

#[throws(std::num::ParseIntError)]
fn fallible_concrete(n: i32) -> i32 {
    match n {
        // implicit return
        0 => 1,
        1 => {
            // explicit return
            return 2;
        },
        2 => {
            #[allow(clippy::all)]
            [3, 4, 5]
                .iter()
                .map(|x| {
                    // doesn't touch return in a closure
                    return x * 2;
                })
                .collect::<Vec<_>>()
                .last()
                .unwrap()
                .clone()
        },
        3 => {
            #[allow(clippy::all)]
            fn double(x: i32) -> i32 {
                let double = x * 2;
                // doesn't touch return in a nested function
                return double;
            }
            double(4)
        },
        4 => {
            // errors can be propagated with ?
            "what".parse()?
        },
        _ => {
            // errors can be returned with throw! (but plain error messages aren't permitted
            // because they don't satisfy the concrete error type)
            let e: std::num::ParseIntError = "what".parse::<i32>().unwrap_err();
            throw!(e)
        },
    }
}