10 releases (5 breaking)

0.5.2 Apr 4, 2021
0.5.1 Feb 18, 2021
0.5.0 Nov 2, 2020
0.4.0 Jun 28, 2020
0.1.0 Nov 21, 2018

#1078 in Rust patterns

Download history 2/week @ 2023-11-20 6/week @ 2023-11-27 34/week @ 2024-02-19 85/week @ 2024-02-26 30/week @ 2024-03-04

149 downloads per month
Used in 4 crates (2 directly)

MIT license

64KB
1K SLoC

Motivation

Emulating checked exceptions in Rust.

Usage

  1. Add this crate to Cargo.toml, and enable any features you want

Cargo.toml:

[dependencies.enumx]
version = "0.4"

[dependencies.cex]
version = "0.5"

Add this if you want to support backtrace:

features = ["log","pretty_log"]

src/lib.rs:

use enumx::export::*;
use enumx::predefined::*; // or use your own enum types at your will.
use cex::*;

Features

  1. ad-hoc enums as checked exceptions.

  2. Backtrace.

  3. Type as pattern.

  4. Fallback as impl Trait.

Documentation

See the enumx book for more.

License

Under MIT.


lib.rs:

Checked EXceptions for Rust.

See the enumx book for more.

Features

  1. Use Result!( Type throws A,B,.. ), ret!(), throw!() to simulate checked exceptions in Rust

  2. #[ty_pat] match for "type as pattern matching" in match expressions.

  3. Optional backtrace support.

  4. Fallback as impl std::error::Error.

Examples

use enumx::export::*;
use enumx::predefined::*;
use cex::*;

// accepts even numbers; rejects odd ones and report an error `String`
#[cex]
fn check_even( a: u32 ) -> Result!( u32 throws String ) {
    if a % 2 == 1 {
        throw!( format!( "odd numbers not allowed: a == {}", a ));
    } else {
        ret!( a );
    }
}

// accepts non-zero numbers; rejects zeros and report an error of `&'static str`
#[cex]
fn check_nonzero( b: u32 ) -> Result!( u32 throws &'static str ) {
    if b == 0 {
        throw!( "zero not allowed: b == 0" );
    } else {
        ret!( b )
    }
}

struct Underflow;

#[cex]
fn sub( a: u32, b: u32 ) -> Result!( u32 throws String, &'static str, Underflow ) {
    let a = check_even( a )?;
    let b = check_nonzero( b )?;
    ret!( a+b );
}

#[cex]
fn distance( a: u32, b: u32 ) -> Result!( u32 throws String, &'static str ) {
    ret!( sub(a,b).or_else( |err| {#[ty_pat] match err {
        Underflow => ret!( b-a ),
        String(s) => throw!( s ),
        TyPat::<&'static str>(s) => throw!( s ),
    }}))
}

#[cex]
fn distance2( a: u32, b: u32 ) -> Result!( u32 throws String, &'static str ) {
    ret!( sub(a,b).or_else( |err| #[ty_pat(gen_throws)] match err {
        Underflow => ret!( b-a ),
    }))
}

#[cex]
fn distance3( a: u32, b: u32 ) -> Result!( u32 throws String, &'static str ) {
    ret!( sub(a,b).or_else( |err| #[ty_pat(gen &'static str, String )] match err {
        Underflow => ret!( b-a ),
    }))
}

Dependencies

~2.5MB
~49K SLoC