How to skip interpolating #value inside quote! macro

I want to generate rust code which uses cpp crate (cpp crate is used for writing inline C++ in Rust).

Everything was working nicely until I had to generate code for including headers:

cpp::cpp! {{
    #include <.../.../header1.hpp>
    #include <.../.../header2.hpp>
}}

The problem is that when I put #include into a quote macro it tries to interpolate it, which I wish it didn't:

...
let cpp_includes = quote::quote! {
    cpp::cpp! {{
        #include <.../.../header1.hpp>
        #include <.../.../header2.hpp>
    }}
};
let cpp_includes = syn::parse2::<syn::Item>(cpp_includes).unwrap();
...

Doesn't work!

Edit:
Using string doesn't work either, as generated code is enclosed in double quotes.

let cpp_includes = "
    #include <.../.../header1.hpp>
    #include <.../.../header2.hpp>
";
let cpp_includes = quote::quote! {
    cpp::cpp! {{
        #cpp_includes
    }}
};
let cpp_includes = syn::parse2::<syn::Item>(cpp_includes).unwrap();

Is bad as well!

I don't see an escaping mechanism documented for quote!, but you can build one yourself by putting a # token in a variable:

let hash =
    proc_macro2::TokenTree::Punct(proc_macro2::Punct::new('#', proc_macro2::Spacing::Alone));

let cpp_includes = quote::quote! {
    cpp::cpp! {{
        #hash include <.../.../header1.hpp>
        #hash include <.../.../header2.hpp>
    }}
};
1 Like

let hash = quote!(#); works as well.

There's also syn::parse_str():

let cpp_includes: TokenStream = syn::parse_str("
    #include <.../.../header1.hpp>
    #include <.../.../header2.hpp>
").unwrap();
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.