Using include_bytes! macro inside another macro

I want to generalize the code which statically compiles several similar assets into the binary, using include_bytes! macro. The only issue is that I need to call it from outer macro, which will be called several times, and it needs to pass the path to data, like this:

// definition
macro_rules! load_sound {
    ($path:literal) => {{
        let score_reached_data = include_bytes!(path);
        Cursor::new(score_reached_data.as_ref())
    }};
}

// usage
let sound1 = load_sound!("../assets/sounds/sound1.ogg");
// sound2, sound3, etc ...

The problem is that it doesn't compile, because not only path needs to be a literal, but it needs to be a string literal, and the issue is that I can't figure out how to express it in macro definition. Is it possible at all?

Error output excerpt:

error: argument must be a string literal
  --> src\game\sounds.rs:5:49
   |
5  |         let score_reached_data = include_bytes!(path);
   |                                                 ^^^^
...
21 |             score_reached: load_sound!("../assets/sounds/score-reached.ogg"),
   |                            ------------------------------------------------- in this macro invocation
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-       let score_reached_data = include_bytes!(path);
+       let score_reached_data = include_bytes!($path);

:wink:

That's just embarrassing how I overlooked the simple syntax error.

Thanks.

1 Like