struct Base {
a: i32
}
#[extend(Base)]
struct B {
b: bool
}
// how to implement extends macro
// expand macro will copy all fields of `struct Base` to B
struct B {
a: i32,
b: bool
}
struct Base {
a: i32
}
#[extend(Base)]
struct B {
b: bool
}
// how to implement extends macro
// expand macro will copy all fields of `struct Base` to B
struct B {
a: i32,
b: bool
}
You don't. The only thing macros have access to are the arguments provided to them. In the case of an attribute macro like this, that would be the single identifier token Base
, and the definition of the struct B
. The extend
macro has absolutely no way of knowing what the definition of Base
is.
One way around this is to introduce another macro attached to Base
which saves the definition of Base
somewhere else so that extend
can read it back later. But, to be honest, I really don't know if that's something you should do. Currently, I believe macros are expanded in lexical order, but I don't know that this will remain true (for example: maybe in the future macros will expand in parallel?).
In addition, it raises questions like "what happens if Base
is in a different module?", "what happens if there's more than one Base
?", "how does this interact with incremental compilation?", etc. Things might have changed, but I'm not aware of the compiler making any guarantees around these.
Also why do you want this behavior? Rust structs doesn't implies indirection, there's no major cost to wrap some fields with a base struct.
Got
I don't think the compiler might support this, and if it does, I think there should be some limitations, such as the need for Base to appear in the context of using macros, and more
I have some similar structs, they have some of the same properties, some are different, I want to be able to reuse existing code when defining it, so that it can be easily modified, I currently use generics
to handle it, but the generics will require me to add a level, so I want to know if it can be solved by macros
struct Base {
base: i32
}
struct A<T> {
base: bool,
a: T
}
struct B<T> {
base: bool,
b: T
}
Here is how you would apply @Hyeonu's suggestion to wrap a base struct, to get the effect shown in your original post.
struct Base {
a: i32,
}
struct B {
base: Base,
b: bool,
}
No generics are needed. Sometimes there is a reason to use generics for a purpose of this kind, but in that case, you would put the generic on the base struct, not the extension:
struct Base<T> {
a: i32,
extra: T,
}
struct B {
b: bool,
}
// then use Base<B> or Base<A>, etc.
yes , That's what I'm doing now. But I had to add one more level.If extend
can be implemented, it can be flatten.