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

macro tyenum_attribute

Attribute macro for type enums

1 unstable release

0.5.0 Apr 19, 2019

#34 in #attribute


Used in tyenum

MIT license

8KB
158 lines

Attribute macro for less verbose creation of enums having different types as variants.

Also automatically implements From, TryFrom and fn is<T>() -> bool to check if its inner item is of type T and is able to give you trait objects depending on which arguments you specify.

Basic Usage:

use tyenum::tyenum;

struct A;
struct B;
struct C;

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

results in:

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

and allows for:

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

Arguments

tyenum also takes 2 optional arguments:

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")
    }
}

This implements std::ops::Deref and std::ops::DerefMut to a trait object of the derived trait for the enum, which allows you to easily call trait methods, which will be redirected to the variant:

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

trait_obj

Requires nightly and #![feature(specialization)] and pollutes your namespace, a trait named "ToTraitObject" will be generated!

#[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")
    }
}

allows you to do this:

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

Dependencies

~2MB
~46K SLoC