Background
I have two similar structs:
mod a {
struct MyStruct {
a: usize,
b: usize,
}
}
mod b {
struct MyStruct {
a: usize,
}
}
And I want to use declarative macro to generate those structs in modules, such as:
macro_rules! my_macro {
() => {
struct MyStruct {
a: usize,
// Not know how to handle conditional compilation
b: usize,
}
};
}
#[cfg] approach, not work
I was thinking about #[cfg] may help, just add #[cfg(my_struct_need_b)] above the b: usize part in the macro rules, like:
macro_rules! my_macro {
() => {
struct MyStruct {
a: usize,
#[cfg(my_struct_need_b)]
b: usize,
}
};
}
But how do I specify my_struct_need_b feature in module a without module b? In C, we can use #define to define a feature, and use #ifdef and #ifndef to control condition compilation, but Rust doesn't provide a functionality similar to #define, and I found in Rust Reference:
It is not possible to set a configuration option from within the source code of the crate being compiled.
So I think #[cfg] may not work.
Optional macro parameter, not work too
Another way is by optional macro parameter:
macro_rules! my_macro {
($($my_b_field: /* no type can work */)?) => {
struct MyStruct {
a: usize,
$($my_b_field)?
}
};
}
And use
mod a {
my_macro!(b: usize);
}
mod b {
my_macro!();
}
But it has two problems:
- The type of
$my_b_fieldcan't be determined. No type can work. - The struct without
bfield may need to be defined via this macro in multiple modules, it is unwise to write some duplicated long code (fieldbis an example, may be a very long fragment) in multiple places.
Problem
How to achieve conditional compilation in macros, and control its behavior via code?