3

I'm trying to pass an argument of my proc_macro as an argument to include_str!, but getting error: argument must be a string literal during the compilation:

/* In lib.rs: */
#[proc_macro]
pub fn include_rsml(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as LitStr);
    let filename = input.value();
    let source_code = include_str!(filename);
    /* ... Do something with source_code and emit TokenStream ... */
}

/* In main.rs: */
include_rsml!("MainWindow.rsml");

Is it possible to do what I want by exploiting the fact that actually we know filename at compile time?

If the only way is to use std::fs file I/O instead of include_str! (which is not a solution I like as least due to the reason that in this way I will have to perform path resolving manually), is there any way to point Cargo that it should rebuild the sources which are depending on MainWindow.rsml if MainWindow.rsml has changed without creating my own build.rs file, in the same way as include_str! does?

vdudouyt
  • 843
  • 7
  • 14
  • How about move `include_str!` out of the `include_rsml` and put it in main.rs? It will look like: `let mystr = include_str!("MainWindow.rsml"); include_rsml!(mystr);`. – Joe_Jingyu Nov 13 '21 at 04:58
  • The problem is that include_rsml! will get literally "mystr" instead of MainWindow.rsml contents in this case. Of course, we could emit the code which deals with it in runtime, but the key idea is to do that in compile time. – vdudouyt Nov 13 '21 at 05:06
  • Actually, you don't know the filename when you compile your `include_rsml` macro. You only know it when you compile your main program, but by that time `include_rsml` has already been compiled. – Jmb Nov 13 '21 at 09:14

0 Answers0