#attributes #derive #macro #tyenum #trait-obj

tyenum_attribute

类型枚举的属性宏

1 个不稳定版本

0.5.0 2019 年 4 月 19 日

#34#attribute


用于 tyenum

MIT 许可证

8KB
158 行(不包括注释)

用于创建具有不同类型变体的枚举的属性宏,更简洁。

同时自动实现 FromTryFromfn is<T>() -> bool 来检查其内部项是否为类型 T,并且能够根据你指定的参数提供 trait 对象。

基本用法

use tyenum::tyenum;

struct A;
struct B;
struct C;

#[tyenum]
enum Test {
    A,
    BB(B),
    C(C),
}

结果为

enum Test {
    A(A),
    BB(B),
    C(C),
}

允许进行

assert_eq!(Test::A(A), A.into());
assert!(Test::A(A).is::<A>());
assert_eq!(Test::A(A).try_into(), Ok(A));

参数

tyenum 还接受 2 个可选参数

derive

#[tyenum(derive=[Display])]
enum Test {
    A,
    BB(B),
}

trait Name {
    fn name(&self) -> String;
}

impl Name for A {
    fn name(&self) -> String {
        String::from("A")
    }
}

impl Name for B {
    fn name(&self) -> String {
        String::from("B")
    }
}

这实现了 std::ops::Derefstd::ops::DerefMut 到枚举派生 trait 的 trait 对象,这允许你轻松调用 trait 方法,这些方法将被重定向到变体

assert_eq!("A", Test::A(A).name());

trait_obj

需要 nightly 和 #![feature(specialization)] 并污染你的命名空间,将生成一个名为 "ToTraitObject" 的 trait!

#[tyenum(trait_obj=[Name])]
enum Test {
    A,
    BB(B),
}

trait Name {
    fn name(&self) -> String;
}

impl Name for A {
    fn name(&self) -> String {
        String::from("A")
    }
}

允许你这样做

fn try_print_name(test: Test) {
    if let Some(named) = test.trait_obj() {
        println!("{}",named.name());
    }
}

依赖关系

~2MB
~46K SLoC