in C#define creates a macro.
in rust to create a macro one uses macro_rules!
that being said macros in C and rust work quite differently so i don't believe you could do it the exact same way. rust requires its macros to output complete items of valid rust syntax.
so a macro could return a struct definition, a function definition, an expression, a type, but not a single field definition.
i see now. the doc was a bit confusing, but after looking at what with_builtin!, it does do what i said it does which is mess with the order of the macro evaluations
here is what i think is a nice easy to reuse system which does require the with_builtin_macros - Rust dependency.
ofc the Operate() system is quite ugly, i would recommend just using semicolons as seperation instead, but i wanted to stay as close to the original as possible.
i would prob use semicolons instead, or anything you feel like using.
I like the discussion. From there I learned several new lessons about Rust like macro_rules!, include_from_root, though it took me a while to understand how to get work. Appreciate it!
One more question. If I want to achieve similar effect in a more Rust way, what would be recommended? It occurs to me that Rust community may have more simple or concise approach than something like 1 to 1/ C to Rust translation.
fn main() {
// Create a path that stores the content to be generated
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("mystruct.rs");
// Write the generated content to the file
fs::write(
&dest_path,
"pub fn mystruct() -> &'static ...,
).unwrap();
}
Then in src/main.rs acquire the function and execute it
well it is a bit unclear to me what exactly you mean to achieve, why not simply declare the struct directly ?
if you need to respect the Operate($ident, $size, $type) for interoperability, i think the include_struct! macro is fine. a build script is also completely reasonable although i personally prefer sticking to simple declarative macros if possible.
ultimaely if you want to declare the strucure of a type in a custom format in an external file, you will need either
a build script
something like include_from_root
or for said file to actually be valid rust, for exampl with a macro. which is kinda what you do in C. your mystruct.def is kinda "valid" C because the Operate are macro calls. to do this in rust you would need mystruct.defto be one macro call. like
I was wondering the same. Possibly, the idea is to have
#define Operate( name, size, type ) ...
#include "def/data/mystruct.def"
at multiple places, with different definitions of Operate that generate whatever code is needed at each place. (That's a macro trick that's sometimes used in C code.)
In Rust, I would probably use one or more traits in this case (maybe one per occurrence of this pattern, but it depends). You can either implement those traits directly for the struct, or via a custom derive implementation if you want to support many different structs. Or if the structs are generated via a macro already, then that macro could also generate the impls along with them.
For example, if you want to implement some kind of compile-time reflection of the struct fields, the corresponding trait could look something like:
The code OP has posted is an example of an X Macro, a somewhat forgotten old metaprogramming technique in C.
It's effectively a compiler-accessible data structure that can be used for code generation. Think derive but somewhat inverted and more ad-hoc. I wrote an explainer a while back that shows how to use X Macros and template headers to implement automatic SoA/AoS conversion. Other things you can do include:
Static reflection for structs and enums by xmacro-ing their fields
You can also add extra metadata to each field by supplying it as additional macro arguments
Generating code to process command-line arguments by xmacro-ing the list of flags
Automatically declaring and loading OpenGL function pointers by name (as opposed to using something like GLAD)
Writing a thread-safe strerror (or equivalent) by xmacro-ing the error codes
Thank you for your advice. Those are helpful! As @Morgane55440 mentions, I will just declare a struct for now. Simpler, the better, at least at this stage to me. Thank you again for all inputs.