0

I need to define many types in one file (->submodule) each and expose them all on the same level of the module. This creates lots of repetitive overhead in the mod.rs:

mod foo;
mod bar;
mod baz;
[...]

pub use self::foo::*;
pub use self::bar::*;
pub use self::baz::*;
[...]

I tried to fix this with a macro, but it does not compile:

macro_rules! expose_submodules {
    ( $( $x:expr ),* ) => {
        $(
            mod $x;
            pub use self::$x::*;
        )*
    };
}

yields

error: expected identifier, found `foo`
 --> src/mod.rs:4:17
  |
4 |             mod $x;
  |                 ^^ expected identifier
  |
 ::: src/mod.rs:10:1
  |
2 | expose_submodules![foo, bar, baz];
  | ----------------------------------------------------------------- in this macro invocation
  |
  = note: this error originates in the macro `expose_submodules` (in Nightly builds, run with -Z macro-backtrace for more info)

(same issue when passing the parameters as strings).

How would I best fix this macro or do the whole task in more idiomatic rust?

philhob
  • 3
  • 3

1 Answers1

0

To fix the macro you need to use ident fragment instead of expr:

macro_rules! expose_submodules {
    ( $( $x:ident ),* ) => {
        $(
            mod $x;
            pub use self::$x::*;
        )*
    };
}
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • Works like a charm, thanks! Do you know whether it is possible to further shorten the code by calling this macro for all submodule files in the same folder? – philhob Jul 02 '23 at 13:24
  • @philhob I don't understand what you mean. – Chayim Friedman Jul 02 '23 at 13:24
  • All "foo", "bar" and "baz" submodules are in the same folder, each in their own file. So there are `mod.rs`, `foo.rs`, ... Is it possible to automatically call the macro (which I call from `mod.rs`) for all modules in the folder, that is all file names minus the `.rs` extension? – philhob Jul 02 '23 at 13:56
  • @philhob No, it is not possible. – Chayim Friedman Jul 02 '23 at 14:34
  • Well it is possible with procedual macros, but not with declarative ones. – cafce25 Jul 02 '23 at 17:37
  • @cafce25 I don't think it is possible with procedural macros either, at least not without nightly APIs. – Chayim Friedman Jul 02 '23 at 17:47