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 ...@@ -5,6 +5,7 @@ package pathfinder
import ( import (
"reflect" "reflect"
"strconv"
"strings" "strings"
) )
...@@ -13,28 +14,35 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) { ...@@ -13,28 +14,35 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) {
keySlice := strings.Split(keyWithDots, ".") keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj) v := reflect.ValueOf(obj)
for _, key := range keySlice[0 : len(keySlice)-1] { for _, key := range keySlice[0:len(keySlice)] {
for v.Kind() == reflect.Ptr {
if v.Kind() == reflect.Invalid { switch v.Kind() {
return nil, newInvalidPathError(keyWithDots) case reflect.Ptr, reflect.Slice, reflect.Array, reflect.Interface:
}
v = v.Elem() v = v.Elem()
} }
if v.Kind() == reflect.Map { switch v.Kind() {
switch v.Type().Key().Kind() { case reflect.Map:
case reflect.String: v = v.MapIndex(reflect.ValueOf(key))
v = v.MapIndex(reflect.ValueOf(key)).Elem() if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
continue }
default:
return nil, newUnsupportedTypePathError(keyWithDots, v.Type()) case reflect.Slice, reflect.Array:
index, err := strconv.Atoi(key)
if err != nil {
return nil, newInvalidPathError(keyWithDots)
} }
} else if v.Kind() != reflect.Struct { v = v.Index(index)
return nil, newUnsupportedTypePathError(keyWithDots, v.Type()) 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 { if v.Kind() == reflect.Invalid {
...@@ -44,26 +52,7 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) { ...@@ -44,26 +52,7 @@ func GetValue[D any](obj D, keyWithDots string) (any, error) {
for v.Kind() == reflect.Ptr { for v.Kind() == reflect.Ptr {
v = v.Elem() 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 return v.Interface(), nil
} }
...@@ -8,6 +8,25 @@ import ( ...@@ -8,6 +8,25 @@ import (
"testing" "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) { func TestGetValueFrom(t *testing.T) {
m := map[string]string{ 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