mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
common/helpers: make some mapstructure hooks work with embedded structs
When using `mapstructure:",squash"`, most structure-specific hook don't dive into the structure as they are provided with the parent structure. Add an helper to make them work on the embedded structure as well and use it for the generic "deprecated fields" hook, but also for the hook for the common Kafka configuration. This is a bit brittle. There are other use cases, but they may not need this change.
This commit is contained in:
@@ -24,11 +24,11 @@ func RegisterMapstructureUnmarshallerHook(hook mapstructure.DecodeHookFunc) {
|
||||
// RegisterMapstructureDeprecatedFields registers a decoder hook removing
|
||||
// deprecated fields. This should only be done during init.
|
||||
func RegisterMapstructureDeprecatedFields[V any](fieldNames ...string) {
|
||||
RegisterMapstructureUnmarshallerHook(func(from, to reflect.Value) (interface{}, error) {
|
||||
RegisterMapstructureUnmarshallerHook(func(from, to reflect.Value) (any, error) {
|
||||
var zeroV V
|
||||
from = ElemOrIdentity(from)
|
||||
to = ElemOrIdentity(to)
|
||||
if to.Type() != reflect.TypeOf(zeroV) {
|
||||
if !SameTypeOrSuperset(to.Type(), reflect.TypeOf(zeroV)) {
|
||||
return from.Interface(), nil
|
||||
}
|
||||
if from.Kind() != reflect.Map {
|
||||
@@ -54,6 +54,24 @@ func RegisterMapstructureDeprecatedFields[V any](fieldNames ...string) {
|
||||
})
|
||||
}
|
||||
|
||||
// SameTypeOrSuperset returns true if "input" and "ref" type are the same or
|
||||
// when "input" has "ref" as a squashed field.
|
||||
func SameTypeOrSuperset(input, ref reflect.Type) bool {
|
||||
if input == ref {
|
||||
return true
|
||||
}
|
||||
if input.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < input.NumField(); i++ {
|
||||
field := input.Field(i)
|
||||
if tag := field.Tag.Get("mapstructure"); tag == ",squash" && field.Type == ref {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMapStructureDecoderConfig returns a decoder config for
|
||||
// mapstructure with all registered hooks as well as appropriate
|
||||
// default configuration.
|
||||
|
||||
Reference in New Issue
Block a user