X macro style rust macros


I am trying to figure out the rust macros, so far I like them a lot. But one thing that I am having trouble is to emulate c style X macros / X includes.

These are used in various places, Clang for example use X includes with a file containing all tokens, the token “database” file is then included in multiple locations, where each includer customise the macros that are used to build up the database. Some includer ensures that they generate a table from the included file, some includer on the other hand generate switch cases and so on.

E.g. mydb.inc

#ifndef FOO #define FOO(a, b) #endif

FOO(blah, 123) FOO(bahh, 123)

#undef FOO

And the includer would then do something like this (here declaring fields in a struct as an example):

#define FOO(a, b) int a; struct foo { #include “mydb.inc” };

The main point here is that the includer can include the database file multiple times, generating different code in context specific cases.

At present I am confused as to how to do similar things in the rust macro system, is it even possible?


Not only is it possible, it’s also encapsulated:

// declaration site
macro_rules! mydb {
    ($foo:ident) => {
        $foo!(blah, 123)
        $foo!(bahh, 123)

// use site
macro_rules! custom_foo {
    ($a:ident, $b:expr) => {
        const $a: int = $b;

@pczarn has worked on enabling Higher-Order Macros (which I like to call HOMies) and they would allow writing this:

// declaration site
macro_rules! mydb {
    ($($foo:tt)*) => {
        macro_rules! foo { $($foo)* }
        foo!(blah, 123)
        foo!(bahh, 123)

// use site
mydb!(($a:ident, $b:expr) => { const $a: int = $b; })


My main problem with this is that something like this doesn’t work:

macro_rules! custom_foo { ($a:ident, $b:expr) => { $a: int, } }

struct Foobar { mydb!(custom_foo); }

macros.rs:30:7: 30:8 error: expected :, found ! macros.rs:30 mydb!(custom_foo);

It seems like the rust parser don’t like macro invocations inside a struct. Is there any reason that this is not possible?


There is no fundamental reason, I don’t think. The current design of macros however requires us to enumerate the locations where they may appear, and the interior of a struct definition did not make the cut (yet?).