TedDriggs / darling

A Rust proc-macro attribute parser
MIT License
983 stars 66 forks source link

Implement `syn::Parse` for `FromMeta` types #285

Open sorcio opened 5 months ago

sorcio commented 5 months ago

I think it should be possible to codegen a syn::Parse implementation for structs that derive From* (I'm only looking at FromMeta because that's what I'm working with, but this can apply to other derive macros).

According to #62 a blanket implementation is not possible, but code generation might very well be, especially if it's opt-in. This works for me and emits errors just as expected:

#[derive(Debug, FromMeta)]
#[darling(syn_parse)]  // <-- attribute name open for bikeshedding
struct MyMacroArgs {
    // ...
}

// generated implementation:
impl Parse for MyMacroArgs {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let items =
            syn::punctuated::Punctuated::<NestedMeta, syn::Token![,]>::parse_terminated(input)?
                .into_iter()
                .collect::<Vec<_>>();
        Ok(MyMacroArgs::from_list(&items)?)
    }
}

This goes through a Vec because FromMeta::from_list takes a slice, but I guess that we could have a method that takes impl IntoIterator (or even implement FromIterator, maybe) to avoid collecting.