Skip to content
Snippets Groups Projects
Verified Commit 8345a09b authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: optimize getter

parent 5d54f927
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ package pathfinder
import (
"reflect"
"strconv"
"strings"
)
......@@ -13,28 +14,35 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) {
keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj)
for _, key := range keySlice[0 : len(keySlice)-1] {
for v.Kind() == reflect.Ptr {
if v.Kind() == reflect.Invalid {
return nil, newInvalidPathError(keyWithDots)
}
for _, key := range keySlice[0:len(keySlice)] {
switch v.Kind() {
case reflect.Ptr, reflect.Slice, reflect.Array, reflect.Interface:
v = v.Elem()
}
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())
switch v.Kind() {
case reflect.Map:
v = v.MapIndex(reflect.ValueOf(key))
if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
}
case reflect.Slice, reflect.Array:
index, err := strconv.Atoi(key)
if err != nil {
return nil, newInvalidPathError(keyWithDots)
}
} else if v.Kind() != reflect.Struct {
return nil, newUnsupportedTypePathError(keyWithDots, v.Type())
v = v.Index(index)
case reflect.Struct:
v = v.FieldByName(key)
if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
}
default:
return nil, newInvalidPathError(keyWithDots)
}
v = v.FieldByName(key)
}
if v.Kind() == reflect.Invalid {
......@@ -44,26 +52,7 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) {
for v.Kind() == reflect.Ptr {
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())
}
v = v.FieldByName(keySlice[len(keySlice)-1])
if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
}
return v.Interface(), nil
}
......@@ -8,6 +8,25 @@ import (
"testing"
)
func TestGetIndexFromArray(t *testing.T) {
m := map[string]any{
"A": "true",
"B": []string{
"1",
"2",
"3",
},
}
v, err := GetValue[map[string]any](m, "B.1")
if err != nil {
t.Error(err)
}
assert.Equal(t, "2", v)
}
func TestGetValueFrom(t *testing.T) {
m := map[string]string{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment