enum_ref_macro

Derive Macro EnumMut

Source
#[derive(EnumMut)]
Expand description

Proc. macro to derive EnumMut trait for the Rust enum.

This generates a new enum that mirrors all variants of the original enum type but wraps all variant field in an exclusive reference. Furthermore it implement the EnumMut trait for the original enum in order to make the generated enum accessible.

ยงExample

use enum_ref::EnumMut;

#[derive(EnumMut)]
#[repr(u8)] // Rust requires this for `B = 42`
enum Test {
    A,
    B = 42,
    C(i32),
    D(i32, i64),
    E { a: i32 },
    F { a: i32, b: i64 },
}

// Access and name the generated `enum` as follows:
type TestMut<'a> = <Test as EnumMut>::Mut<'a>;

// Creates reference wrappers of `enum` instances as follows:
let mut test0 = Test::C(42);
let mut test1 = test0.clone();
let test_ref: TestMut = <Test as EnumMut>::as_mut(&mut test0);
match (&mut test1, test_ref) {
    (Test::C(a0), TestMut::C(a1)) => assert_eq!(a0, a1),
    _ => panic!("something wen't wrong ..."),
}

The #[derive(EnumMut)] in the above example will generate roughly the following Rust code.

const _: () = {
    #[derive(::core::fmt::Debug)]
    #[repr(u8)]
    pub enum TestMut<'__enum_ref_lt> {
        A,
        B = 42,
        C(&'__enum_ref_lt mut i32),
        D(&'__enum_ref_lt mut i32, &'__enum_ref_lt mut i64),
        E {
            a: &'__enum_ref_lt mut i32,
        },
        F {
            a: &'__enum_ref_lt mut i32,
            b: &'__enum_ref_lt mut i64,
        },
    }

    impl ::enum_ref::EnumMut for Test {
        type Mut<'__enum_ref_lt> where Self: '__enum_ref_lt =
                TestMut<'__enum_ref_lt> where Self: '__enum_ref_lt;
        fn as_mut(&mut self) -> <Self as ::enum_ref::EnumMut>::Mut<'_> {
            type __enum_ref_EnumMut_Mut<'__enum_ref_lt> =
                <Test as ::enum_ref::EnumMut>::Mut<'__enum_ref_lt>;
            match self {
                Self::A => __enum_ref_EnumMut_Mut::A,
                Self::B => __enum_ref_EnumMut_Mut::B,
                Self::C(_0) => __enum_ref_EnumMut_Mut::C(_0),
                Self::D(_0, _1) => __enum_ref_EnumMut_Mut::D(_0, _1),
                Self::E { a } => __enum_ref_EnumMut_Mut::E { a },
                Self::F { a, b } => __enum_ref_EnumMut_Mut::F { a, b },
            }
        }
    }
};