I have a method for convert()
that I use on various subtypes of a ConfigStruct
type, to initialize from a dictionary. For a couple of subtypes, I want to define specific behaviors (e.g., catch deprecated keys and map them to their updated names), then call the general method. Here’s the idea, pared way down:
import Parameters: @with_kw
abstract type ConfigStruct end
@with_kw struct C1 <: ConfigStruct
a::String
end
@with_kw struct C2 <: ConfigStruct
b::String
end
function Main.convert(::Type{T}, d::Dict{Symbol}) where {T<:ConfigStruct}
@info "Converting $T, generic"
return T(; d...)
end
function Main.convert(::Type{T}, d::Dict{Symbol}) where {T<:C2}
@info "Converting $T, specific"
# ...convert, then call other method
return invoke(convert, Tuple{Type{ConfigStruct},Dict{Symbol}}, (T, d))
end
s1::C1 = Dict(:a => "a")
s2::C2 = Dict(:b => "b")
Unfortunately, this usage of invoke()
doesn’t work, I get this error on the final line of code:
[ Info: Converting C2, specific
ERROR: invoke: argument type error
I’ve tried several variations on that invoke()
, does anyone have any guidance?