proc_macro2::TokenStream to syn::ParseBuffer?

I have a proc macro crate where I use syn::Attribute::parse_outer to parse some part of the macro input to syn::Attribute.

I want to parse the attribute tokens (the tokens field Attribute in syn - Rust) using syns parsers and macros like parenthesized, but I can't find how to convert a &proc_macro2::TokenStream (type of the tokens field) to syn::ParseBuffer (input expected by syn's parsers).

Here's the full example: Rust Explorer

fn test(attr: &syn::Attribute) {
    let attr_tokens_with_parens = attr.tokens;
    let attr_tokens;
    syn::parenthesized!(attr_tokens in attr_tokens_with_parens);
}

How do I convert a &proc_pacro2::TokenStream to syn::ParseBuffer?

You should use the handy parse_meta to get the token in an attribute.

2 Likes

You use Parser::parse2():

::syn::parse::Parser::parse2(
    |input: ParseStream<'_>| ::syn::Result::Ok({
        …
    }),
    attr.tokens.clone(),
)? // <- try to have all of your proc-macro functions return a `::syn::Result`

If you directly want to use Punctuated::parse_… function, you can skip the closure wrapper and directly feed that function (the savy term for this is called eta reduction):

::syn::parse::Parser::parse2(
    Punctuated::<…, Token![,]>::parse_terminated,
    attr.tokens.clone(),
)

And if you wanted, you could try to use syn's style, but which I personally find very ahrd to read when you don't know about the contrived Parser-extension-trait design:

use ::syn::parse::Parser;

/* many lines in between… */

// ??
Punctuated::<…, Token![,]>::parse_terminated.parse2(attr.tokens.clone())
3 Likes