TedDriggs / darling

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

Parsing non-string attribute macro arguments #216

Closed jonasbb closed 1 year ago

jonasbb commented 1 year ago

Hi, I am wondering if it is possible to process attribute macro arguments if they do not follow the syn::Meta pattern. As part of https://github.com/jonasbb/serde_with/issues/533 I am currently evaluating if I can use non-string proc macro arguments. But I am stuck on how I can process the arguments of my proc macro attribute.

The idea is to specify an attribute #[serde_as(crate = ::s_with)]. Here, the ::s_with is the non-string part. The args of the proc macro only covers these tokens crate = ::s_with.

#[proc_macro_attribute]
pub fn serde_as(args: TokenStream, input: TokenStream) -> TokenStream { /* ... */ }

The problem is now that none of the From* traits seem to cover this use case. With string arguments, i.e., crate = "::s_with" this follows the syntax of a syn::Meta, or more specific AttributeArgs. But this does not work with the non-string variant, since the right-hand side is not a literal value. Right now, I am not aware of any type available in syn which covers such arbitrary shaped macro arguments, except just using TokenStream. But there is no FromTokenStream trait to go with it in darling.

There are some unreleased changes in syn which affect the types Attribute and AttributeArgs. This might make supporting non-string arguments easier in the future.

I just want to know if you have a better idea how to support this. For now, the only way I see is creating an artificial Attribute with the args TokenStream and using FromAttributes afterwards.

TedDriggs commented 1 year ago

This is not supported today. It's come up in #96, but mostly in the context of improving errors for that situation.

The closest I've come to finding a solution is #186, which creates a new Meta that is generic over the eventual right-hand side of the = token, allowing there to be things besides syn::Lit there. That said...

  1. You can see that the branch is not close to being ready to merge
  2. Doing this any other way would add significant complexity to custom FromMeta impls (possibly to the point of forcing people into using the derived impl, which I don't like)
  3. I'm not convinced that saving the quotation marks is worth it for the ecosystem as a whole, or for darling in particular.
jonasbb commented 1 year ago

Thanks for the response. I was mainly interested in what the status is. Overall, I don't think it is that important to support, but it might work a bit nicer with IDE autocompletion, although when I just tested it with rust-analyzer I didn't see anything so far. I will definitely wait and see what kind of syn changes are upcoming and if they make this easier in the future.