How to extends pre defined struct's field at compile time using macro?

How to extends pre defined struct's field at compile time using macro?

E.g.

#[derive(Default)]
struct Person {
    pub name: String,
    pub age: u32,
}

impl Person {
    pub fn new() -> Person {
        Default::default()
    }
}

let person = Person::new();

// new_value can be string, number, struct, vector or any other ...
let person = some_macro!(person, "new_field", "new_value");

I don't think it is possible, as macros are expanded before type checking. your macro will see the identifier person, but it wouldn't know the type of it.

You can't do this in exactly this form using a macro. Macros don't have access to type information, so unless you invoke the macro with the definition of the struct syntactically inlined into the macro call itself, it stands no chance of knowing what fields a given type has.

What high-level problem are you trying to solve?

2 Likes

Thanks
Could you please give me an example in other way? which is possible?

Why do you need this? There's probably a better solution to your high-level problem.

1 Like

This isn't possible, and from Rust's perspective it's a weird thing to ask for. You probably need to take a step back and look for a different approach.

Structs have to be completely defined in their original definition location. Even if you involved a macro in generation of the struct Person syntax, you'd still need to define all fields in the same place anyway, so there's no point complicating this with any macros. Just use the basic struct syntax and list all the fields there in a normal way.

If you have arbitrary key-value pairs to add, you could add a HashMap or enum_map field to Person, but that is a run-time solution.

If the fields are really hard to write out by hand (e.g. they come from some external schema file), you could create a build.rs script that generates Rust source code with definition of struct Person with the fields, but that's a bit complicated, so I don't recommend going that route unless you really need to.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.