Macro tagged_union_with_jump_tables

Source
macro_rules! tagged_union_with_jump_tables {
    (
        #[repr($discriminant_type: ident)]
        $( #[$attr: meta] )*
        $visibility: vis enum $EnumName: ident {
            $(
                $Variant: ident $(
                    (
                        $(
                            $variant_field_type: ty
                        ),*
                        $(,)?
                    )
                )?
            ),*
            $(,)?
        }

        $($tail: tt)*
    ) => { ... };
    (
        @methods
        $discriminant_type: ident
        $EnumName: ident { $( $Variant: ident ($( $variant_field_type: ty )*) )* }

        pub $visibility: vis fn $method: ident(
            &self
            $( , $arg: ident: $arg_type: ty)*
            $(,)?
        ) $( -> $ret: ty )?  {
            match *self {
                $(
                    $ReEnumName: ident::$MatchedVariant: ident $( (
                        $(ref $matched_field: ident),* $(,)?
                    ) )?
                    =>  $block: block
                )*
            }
        }

        $($tail: tt)*
    ) => { ... };
    (
        @methods
        $discriminant_type: ident
        $EnumName: ident { $( $Variant: ident $( ($( $variant_field_type: ty )*) )? )* }
    ) => { ... };
    (
        @closures_table
        $EnumName: ident $discriminant_type: ident
        [ $($arg: ident)* ]
        [
            $Variant: ident
            ($( $variant_field_type: ty )*)
            $($variants_tail: tt)*
        ]
        [
            $ReEnumName: ident $MatchedVariant: ident
            ($( $matched_field: ident )*)
            $block: block
            $($matched_tail: tt)*
        ]
        [ $($previous_closures: tt)* ]
    ) => { ... };
    (
        @closures_table
        $EnumName: ident $discriminant_type: ident
        [ $($arg: ident)* ]
        [ ]
        [ ]
        [ $($closures: tt)* ]
    ) => { ... };
    (@assert_ident_is_int u8) => { ... };
    (@assert_ident_is_int u16) => { ... };
    (@assert_ident_is_int u32) => { ... };
    (@assert_ident_is_int u64) => { ... };
    (@assert_ident_is_int i8) => { ... };
    (@assert_ident_is_int i16) => { ... };
    (@assert_ident_is_int i32) => { ... };
    (@assert_ident_is_int i64) => { ... };
    (@assert_idents_equal expected = $expected: ident, found = $found: ident) => { ... };
}
Expand description

Create an enum with methods that match on it, where matching is implemented as a jump table (static array of function pointers, indexed by discriminant).

This is based on RFC 2195: https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html

See usage example in test at the end of this file