From e1672c7f32df59a635d06d67e1ddc67a210c6585 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 15 Feb 2025 14:25:54 +0100 Subject: [PATCH] common/helpers: fix decoding of strings as slice We use the previous version of the function from upstream. --- common/helpers/mapstructure.go | 23 ++++++++++++++++++++++- common/helpers/mapstructure_test.go | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/common/helpers/mapstructure.go b/common/helpers/mapstructure.go index 69e06a68..23dba6d1 100644 --- a/common/helpers/mapstructure.go +++ b/common/helpers/mapstructure.go @@ -36,12 +36,33 @@ func GetMapStructureDecoderConfig(config interface{}, hooks ...mapstructure.Deco mapstructure.ComposeDecodeHookFunc(mapstructureUnmarshallerHookFuncs...), mapstructure.TextUnmarshallerHookFunc(), mapstructure.StringToTimeDurationHookFunc(), - mapstructure.StringToSliceHookFunc(","), + StringToSliceHookFunc(","), ), ), } } +// StringToSliceHookFunc returns a DecodeHookFunc that converts +// string to []string by splitting on the given sep. +func StringToSliceHookFunc(sep string) mapstructure.DecodeHookFunc { + return func( + f reflect.Kind, + t reflect.Kind, + data interface{}, + ) (interface{}, error) { + if f != reflect.String || t != reflect.Slice { + return data, nil + } + + raw := data.(string) + if raw == "" { + return []string{}, nil + } + + return strings.Split(raw, sep), nil + } +} + // ProtectedDecodeHookFunc wraps a DecodeHookFunc to recover and returns an error on panic. func ProtectedDecodeHookFunc(hook mapstructure.DecodeHookFunc) mapstructure.DecodeHookFunc { return func(from, to reflect.Value) (v interface{}, err error) { diff --git a/common/helpers/mapstructure_test.go b/common/helpers/mapstructure_test.go index aa9de381..ea21e602 100644 --- a/common/helpers/mapstructure_test.go +++ b/common/helpers/mapstructure_test.go @@ -37,6 +37,28 @@ func TestMapStructureMatchName(t *testing.T) { } } +func TestStringToSliceHookFunc(t *testing.T) { + type Configuration struct { + A []string + B []int + } + TestConfigurationDecode(t, ConfigurationDecodeCases{ + { + Initial: func() interface{} { return Configuration{} }, + Configuration: func() interface{} { + return gin.H{ + "a": "blip,blop", + "b": "1,2,3,4", + } + }, + Expected: Configuration{ + A: []string{"blip", "blop"}, + B: []int{1, 2, 3, 4}, + }, + }, + }) +} + func TestProtectedDecodeHook(t *testing.T) { var configuration struct { A string