1 个不稳定版本

0.1.0 2019 年 5 月 19 日

#94#错误处理

MIT/Apache

9KB
68

属性 #[power_set_enum] 将枚举类型参数化为幂集(所有子集的集合),并为该枚举创建具有相同名称的宏,以便于子集的表示。

注意:这是一个夜间构建的包,要使用它您需要启用以下功能标志

#![feature(never_type, exhaustive_patterns, proc_macro_hygiene)]

#[power_set_enum] 装饰的枚举的每个变体都必须是一个只有一个元素的元组结构体变体,并且该元素的类型必须在该枚举中是唯一的。不支持枚举的参数化(除由 #[power_set_enum] 创建的参数化之外)。

要使用特定的参数化,请使用与枚举具有相同名称的宏,并提供所需的类型列表。

在枚举类型上创建了一个 upcast 方法,用于将任何子集转换为任何超集。通常与 Result::map_err 一起使用。

fn foo(...) -> Result<..., E![A, B]> {
    ...
}
fn bar(...) -> Result<..., E![A, B, C, D]> {
    foo(...).map_err(E::upcast)
}

Extract 特质为枚举类型和具有枚举作为错误的 [Result] 提供了一个 extract 方法,用于提取一个新的 [Result],其中 OK 值是不带提取变体的原始值,错误是提取的变体。

fn baz(...) -> Result<..., E![A, B, D]> {
    bar(...).extract::<C>().expect("C is not allowed at all")
}
#![feature(never_type, exhaustive_patterns, proc_macro_hygiene)]

pub struct Exception1;
pub struct Exception2;
pub struct Exception3;

#[powerset_enum]
pub enum Error {
    Exception1(Exception1),
    Exception2(Exception2),
    Exception3(Exception3),
}

fn foo(x: usize) -> Result<usize, Error![Exception1, Exception2]> {
    Ok(match x {
        1 => Err(Exception1)?,
        2 => Err(Exception2)?,
        x => x,
    })
}

fn bar(x: usize) -> Result<usize, Error![Exception1, Exception3]> {
    if x == 3 {
        Err(Exception3)?;
    }
    foo(x)
        // Specifically handle `Exception2`:
        .extract::<Exception2>().unwrap_or(Ok(2))
        // Convert `Result<usize, Error![Exception1]>` to `Result<usize, Error![Exception1, Exception3]>`:
        .map_err(Error::upcast)
}

fn main() {
    let x = 1;

    match foo(x) {
        Ok(n) => println!("OK - got {}", n),
        Err(Error::Exception1(_)) => println!("Got exception 1"),
        Err(Error::Exception2(_)) => println!("Got exception 2"),
        // No Exception3 match arm needed - `foo` cannot return it
    }

    match bar(x) {
        Ok(n) => println!("OK - got {}", n),
        Err(Error::Exception1(_)) => println!("Got exception 1"),
        // No Exception2 match arm needed - `bar` cannot return it
        Err(Error::Exception3(_)) => println!("Got exception 3"),
    }
}

依赖关系

~2MB
~46K SLoC