#enums #variant #macro #generate #newtype #values #macro-derive

macro enumorph

Derive macro to generate TryFrom and From implementations for converting between newtype enum variants and their wrapped values

3 releases

0.1.2 Oct 30, 2023
0.1.1 Oct 30, 2023
0.1.0 Oct 30, 2023

#355 in Procedural macros

Download history 3/week @ 2024-02-14 19/week @ 2024-02-21 10/week @ 2024-02-28 1/week @ 2024-03-13 26/week @ 2024-03-27 35/week @ 2024-04-03

61 downloads per month

MIT/Apache

9KB
151 lines

Enumorph

Derive macro to generate TryFrom and From implementations for converting between newtype enum variants and their wrapped values.

use std::fmt::Display;

use enumorph::Enumorph;

#[derive(Enumorph)]
enum Enum<T: ToOwned + ?Sized, U>
where
    U: Display,
{
    A(A<T>),
    B {
        b: B<U>,
    },
    #[enumorph(ignore)]
    C,
    #[enumorph(ignore)]
    D {
        e: u8,
        f: bool,
    },
}

struct A<T: ToOwned + ?Sized>(T::Owned);

struct B<U: Display>(U);

fn main() {
    assert!(matches!(
        Enum::<str, u8>::from(A("a".to_owned())),
        Enum::A(A(_))
    ));

    assert!(matches!(
        A::try_from(Enum::<str, u8>::A(A("a".to_owned()))),
        Ok(A(_))
    ));

    assert!(matches!(Enum::<str, u8>::from(B(1)), Enum::B { b: B(1) }));

    assert!(matches!(
        B::try_from(Enum::<str, u8>::B { b: B(1) }),
        Ok(B(1))
    ));

    assert!(matches!(B::try_from(Enum::<str, u8>::C), Err(Enum::C)));
}

Limitations

If two variants "wrap" the same type, then the resulting From and TryFrom implementations will overlap. In this case, you can wrap the inner type in a newtype:

#[derive(Enumorph)]
enum T {
    U(U),
    V(V),
}

struct U(String);
struct V(String);

Dependencies

~305–760KB
~18K SLoC