3
votes

I am building a small HTML parser in Rust using syn and proc_macro2. I have made it so far that i can parse regular HTML tags and it's attributes So for example

html!(
 <div>
   <image></image>
 </div>
)

Works

But i would like to parse some JSX style code aswell, so something like this

html!(
 <div>
     {
      (0..3).map(|| html!(<text value="new"></text>))
     } 
 </div>
)

Here is my problem, i can't figure out how to parse the code between the brackets inside my macro_code, i would like to get Vector with just <text></text> elements.

Here is a playground example

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d0a899ee52772565d4043fea24d8f21d

1
Hey, how are you even able to use html!(..) instead of html! { .. } with proc macros? Don't proc macros always have to be wrapped in braces and not in parens?balanceglove2

1 Answers

2
votes

I finally figured out an answer for my problem and decided to share it, for anyone else struggling with it too.

It's super easy if you understand the concept of what an expression means in macro. the whole code between {} is an expression and when returning the macro result, you can use it as value inside tokens.

Small example

impl ToTokens for Response {
fn to_tokens(&self, tokens: &mut TokenStream) {
    let expressions: Vec<Expr> = self.expressions.clone();
    let entries: Vec<u16> = self.values.clone();

    //We can now use our saved numbers and expressions in this quote! and return something totally new to the user.
    tokens.extend(quote! {
       {
            let mut data: Vec<u16> = vec!(#(#entries),*);
            let expressions: Vec<Vec<u16>> = vec!(#(#expressions),*);
            for expr in expressions {
                data.extend(expr);
            };
           data.iter().fold(0, |acc, len| acc + len )
       }
    });
}