#enums #variant #macro #generate #newtype #values #converting

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

#1769 in Procedural macros

Download history 13/week @ 2024-11-13 2/week @ 2024-11-20 3/week @ 2024-11-27 6/week @ 2024-12-04 14/week @ 2024-12-11 1/week @ 2024-12-18 4/week @ 2025-01-08 8/week @ 2025-01-15 7/week @ 2025-01-22 8/week @ 2025-02-05 27/week @ 2025-02-12 16/week @ 2025-02-19 29/week @ 2025-02-26

80 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

~185–610KB
~14K SLoC