#type #enum #sum #tagged #union

nightly tyenum

Attribute macro for type enums

4 releases (2 breaking)

0.5.0 Apr 19, 2019
0.2.1 Apr 14, 2019
0.2.0 Apr 14, 2019
0.1.0 Apr 13, 2019

#1321 in Rust patterns

34 downloads per month

MIT license

5KB

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

~1.5MB
~43K SLoC