Expand description

This crate contains a procedural macro attribute that can be placed on an impl block. It will generate an enum based on the functions defined in the impl block. The generated enum will have a variant for each function, and a new function map will be added to the impl block that will call the appropriate function based on the variant.

An example:

#[enum_from_functions]
impl Enum {
    fn foo() -> &'static str {
        "Foo"
    }
    fn bar() -> &'static str {
        "Bar"
    }

    fn baz() -> &'static str {
        "Baz"
    }
}

expands to:

enum Enum {
    Foo,
    Bar,
    Baz,
}

impl Enum {
    fn foo() -> &'static str {
        "Foo"
    }
    fn bar() -> &'static str {
        "Bar"
    }
    fn baz() -> &'static str {
        "Baz"
    }

    fn map(&self) -> &'static str {
        match self {
            Enum::Foo => Enum::foo(),
            Enum::Bar => Enum::bar(),
            Enum::Baz => Enum::baz(),
        }
    }
}

The signatures of all the functions in the impl block must be the same and must not use the self keyword. Aside from that, any function signature will work with this macro.

#[enum_from_functions]
impl Enum {
    // Causes a compile error because the `self` argument isn't allowed.
    fn foo(self) -> &'static str {
        "Foo"
    }
}
// Causes a compile error because the return types don't match.
#[enum_from_functions]
impl Enum {
    fn foo() -> &'static str {
        "Foo"
    }
    fn bar() -> String {
        "Bar".to_owned()
    }
}
// Causes a compile error because the argument types don't match.
#[enum_from_functions]
impl Enum {
    fn foo(_: i32) -> &'static str {
        "Foo"
    }
    fn bar(_: bool) -> &'static str {
        "Bar"
    }
}

If you need to export the generated enum type out of its parent module, provide the pub argument to the macro attribute.

mod internal {
    #[enum_from_functions(pub)]
    impl Visible {
        fn example() -> bool {
            true
        }
    }
}

use internal::Visible;
fn main() {
    Visible::map(Visible::Example);
}

Items in the impl block that are not functions will be ignored and passed through to the output unchanged. Similarly, any attributes applied before or after the macro attribute will be applied to the generated enum declaration.

#[enum_from_functions]
#[derive(Debug)]
impl Enum {
    const FOO: &'static str = "Foo";
    fn foo() -> &'static str {
        Self::FOO
    }

    const BAR: &'static str = "Bar";
    fn bar() -> &'static str {
        Self::BAR
    }

    const BAZ: &'static str = "Baz";
    fn baz() -> &'static str {
        Self::BAZ
    }
}

Attribute Macros

  • A procedural macro attribute that generates an enum based on the functions defined in the impl block it annotates. See the crate documentation for more information.