I'm trying to write a macro that extends an existing macro with some additional variants.
Example:
enum MyEnum {
VariantA,
VariantB,
}
extend_enum!("MyExtendedEnum", MyEnum);
fn main() {
// variants from original enum...
let a = MyExtendedEnum::VariantA;
let b = MyExtendedEnum::VariantB;
// plus the new variants...
let c = MyExtendedEnum::VariantC;
let d = MyExtendedEnum::VariantD;
}
I've used a procedural macro which accepts the original enum name as an Ident
. I'm stuck on how to get the enum variants from the Ident
.
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse::{Parse, ParseStream}, parse_macro_input, Ident, LitStr, Token};
struct ExtendEnumInput {
extended_enum_name: LitStr,
base_enum: Ident,
}
impl Parse for ExtendEnumInput {
fn parse(input: ParseStream) -> syn::Result<Self> {
let extended_enum_name = input.parse()?;
input.parse::<Token![,]>()?;
let base_enum = input.parse()?;
Ok(ExtendEnumInput {
extended_enum_name,
base_enum,
})
}
}
#[proc_macro]
pub fn extend_enum(input: TokenStream) -> TokenStream {
let ExtendEnumInput { extended_enum_name, base_enum} = parse_macro_input!(input as ExtendEnumInput);
let enum_name = format_ident!("{}", extended_enum_name.value());
let original_variants = todo!();
let output = quote! {
enum #enum_name {
#(
#original_variants,
)*
VariantC,
VariantD,
}
};
TokenStream::from(output)
}
I've tried using ItemEnum
instead of Ident
but this fails to compile with an error saying it expects an enum
.