Mixers.jl will work, but it ends up constructing a whole bunch of macros. I managed to build a single macro that does what I need it to do, and handles parametric types.
function get_type_expression(X::Union{Symbol,DataType})
if X isa Symbol
return X
elseif X isa DataType
Params = X.parameters
if isempty(Params)
return Symbol(X.name.wrapper)
else
return Expr(:curly, Symbol(X.name.wrapper), Params...)
end
end
end
macro inherit_fields(AssetTypeExp::Expr)
BaseAssetType = Core.eval(@__MODULE__, AssetTypeExp.args[1])
TypeSymbols = AssetTypeExp.args[2:end]
AssetType = BaseAssetType{TypeSymbols...}
ex = Expr(:block)
for fName in fieldnames(AssetType)
fType = fieldtype(AssetType, fName)
fTypeParsed = get_type_expression(fType)
push!(ex.args, :( $fName :: $fTypeParsed ) )
end
return esc(ex)
end
You can then use this macro pretty intuitively as follows:
mutable struct MyOldType{T}
Name :: Symbol
A :: T
B :: T
V :: Vector{T}
end
mutable struct MyNewType{T}
@inherit_fields(MyOldType{T})
C :: T
end
As you can see, it’s all done in one neat step without building a whole bunch of specific macros as you would do in Mixers.jl. You can even modify this by adding a second argument that lists fields you want to leave out of the inheritance and filtering those out of the for loop (keep in mind that the field array will be an expression so you will have to evaluate it to get an array of Symbols).