0
votes

I'm a rust newbie, I started one week ago but this language is already very exciting. I'm rewritting a nodejs project in rust to get better performance and for the moment it's just crazy how faster it is.

I'm actually writting a proc_derive_macro (using the "syn" crate) to generate method on some specific struct. I'm almost done but i don't find how to generate enum variant. I will try to explain myself.

That's my code generation (using quote!)

quote! {
        // The generated impl.
        impl #name /*#ty_generics #where_clause*/ {
            pub fn from_config(config: &IndicatorConfig) -> Result<Self, Error> {
                let mut #name_lower = #name::default()?;
                for (k, v) in config.opts.iter() {
                    println!("{:?} {:?}", k, v);
                    match (k.as_str(), v) {
                        ("label", Values::String(val)) => {
                            #name_lower.label = val.clone();
                        }
                        ("agg_time", Values::String(val)) => {
                            #name_lower.agg_time = Some(val.clone());
                        }
                        #(
                            (#fields_name_str, Values::Unteger(val)) => {
                                #name_lower.#fields_name = val.clone();
                            }
                        )*
                        (&_, _) => {}
                    }
                }
                #name_lower.init()?;
                Ok(#name_lower)
            }
        }
    };

As we can see I'm generating much of my code here

(#fields_name_str, Values::Unteger(val)) => {
   #name_lower.#fields_name = val.clone();
}

But I didn't find a way to generate an "enum variant for the matching" (I don't know how we call that, i hope you will understand):

Values::String(val)
OR
Values::Unteger(val)
...

I'm writting a function which will create the variant matching according to parameter type found inside the struct:

fn create_variant_match(ty: &str) -> PatTupleStruct {
    let variant = match ty {
        "u32" => Ident::new("Unteger", Span::call_site()),
        ...
        _ => unimplemented!(),
    };
}

Actually I'm creating an Ident but I want to create the "enum variant match" -> Values::Unteger(val).

I watched the doc of the syn crate, spend hours trying to find a way, but it's a bit complex for my actual level, so I hope someone will explain me how to do that.

1

1 Answers

1
votes

I found a simple way of doing that. Just need to parse a string (which i can format before) using the syn parser. Didn't think about it before was trying to construct the Expr by hand (a bit stupid ^^)

syn::parse_str::<Expr>("Values::Unteger(val)")

which will generate the Expr needed