diff --git a/get.go b/get.go index 9fbd303858c2f2f8300002ccd0b4ed5a84f65cb8..a49d98521cceebed4e8c67da422aeedcb4a32a94 100644 --- a/get.go +++ b/get.go @@ -21,7 +21,16 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) { v = v.Elem() } - if v.Kind() != reflect.Struct { + if v.Kind() == reflect.Map { + switch v.Type().Key().Kind() { + case reflect.String: + v = v.MapIndex(reflect.ValueOf(key)).Elem() + + continue + default: + return nil, newUnsupportedTypePathError(keyWithDots, v.Type()) + } + } else if v.Kind() != reflect.Struct { return nil, newUnsupportedTypePathError(keyWithDots, v.Type()) } @@ -36,6 +45,15 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) { v = v.Elem() } + if v.Kind() == reflect.Map { + switch v.Type().Key().Kind() { + case reflect.String: + return v.MapIndex(reflect.ValueOf(keySlice[len(keySlice)-1])).Interface(), nil + default: + return nil, newUnsupportedTypePathError(keyWithDots, v.Type()) + } + } + // non-supporter type at the top of the path if v.Kind() != reflect.Struct { return nil, newUnsupportedTypeAtTopOfPathError(keyWithDots, v.Type()) diff --git a/get_test.go b/get_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d079fa3e662362c1b0a1e4f0936bc149775955eb --- /dev/null +++ b/get_test.go @@ -0,0 +1,81 @@ +// Copyright 2022 schukai GmbH +// SPDX-License-Identifier: AGPL-3.0 + +package pathfinder + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetValueFrom(t *testing.T) { + + m := map[string]string{ + "KeyA": "true", + "KeyB": "2", + "KeyC": "3", + "KeyD": "4.0", + } + + v, err := GetValue[map[string]string](m, "KeyA") + if err != nil { + t.Error(err) + } + + assert.Equal(t, v, "true") + +} + +func TestPathGetValueFromX(t *testing.T) { + m := map[string]any{ + "A": "true", + "B": map[string]any{ + "C": 2, + "D": map[string]any{ + "E": "3", + }, + }, + "X": "3", + "Y": "4.0", + } + + v, err := GetValue[map[string]any](m, "B.D.E") + if err != nil { + t.Error(err) + } + + assert.Equal(t, "3", v) + + v, err = GetValue[map[string]any](m, "B.C") + if err != nil { + t.Error(err) + } + + assert.Equal(t, 2, v) + +} + +func TestPathGetValueFrom(t *testing.T) { + + type PathfindTestStruct1 struct { + A bool + Sub1 struct { + B int + Sub2 struct { + C bool + } + D int + } + } + + var testData PathfindTestStruct1 + testData.A = true + testData.Sub1.B = 2 + testData.Sub1.Sub2.C = true + testData.Sub1.D = 4 + + GetValue[PathfindTestStruct1](testData, "Sub1.B") + GetValue[PathfindTestStruct1](testData, "Sub1.Sub2.C") + GetValue[PathfindTestStruct1](testData, "Sub1.D") + +}