dtolnay / quote

Rust quasi-quoting
Apache License 2.0
1.32k stars 90 forks source link

[feature]Support insert method call #274

Closed yyy33 closed 4 months ago

yyy33 commented 4 months ago
// You can see that every time I interpolate types I need to define an extra variable
//and then clone it
fn automap(n: usize) -> TokenStream2 {
    let types = (1..=n).map(|n| format_ident!("T{}", n));
    let types2 = types.clone();
    let fields = (1..=n).map(|n| format_ident!("map{}", n));
    quote! {
        pub struct AutoMap<#(#types),*> {
            #( #fields: BaseMap<#types2> ),*
        }
    }
}
//I want to define an additional gen_types function and then call it when interpolating
fn automap(n: usize) -> TokenStream2 {
    let fields = (1..=n).map(|n| format_ident!("map{}", n));
    quote! {
        //`#gen_types(n)` call the `gen_types(n)` and insert the result
        pub struct AutoMap<#gen_types(n)> {
            #( #fields: BaseMap<#gen_types(n)> ),*
        }
    }
}

fn gen_types(n: usize) -> TokenStream2 {
    let i = (1..=n).map(|n| format_ident!("T{}", n));
    quote!{ #(#i),* }
}
dtolnay commented 4 months ago

I would prefer not to build this into this crate. I think the original snippet using types.clone() is all right as is.

You can also write let types: Vec<_> = (1..=n).map(...).collect(); and use #types twice.

yyy33 commented 4 months ago

let types: Vec<_> = (1..=n).map(...).collect();

It worked. Thank you