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

feat: new find method for paths #12

parent 91924423
No related branches found
No related tags found
No related merge requests found
find.go 0 → 100644
package pathfinder
import (
"fmt"
"reflect"
"strings"
)
func FindPaths(v reflect.Value, targetType reflect.Type, path []string, paths *[]string) {
if v.Kind() == reflect.Invalid {
return
}
vType := v.Type()
switch v.Kind() {
case reflect.Ptr:
FindPaths(v.Elem(), targetType, path, paths)
case reflect.Struct:
for i := 0; i < v.NumField(); i++ {
newPath := append(path, vType.Field(i).Name)
FindPaths(v.Field(i), targetType, newPath, paths)
}
case reflect.Map:
for _, key := range v.MapKeys() {
newPath := append(path, fmt.Sprint(key))
FindPaths(v.MapIndex(key), targetType, newPath, paths)
if v.MapIndex(key).Type() == targetType {
*paths = append(*paths, strings.Join(newPath, "."))
}
}
case reflect.Slice, reflect.Array:
for i := 0; i < v.Len(); i++ {
newPath := append(path, fmt.Sprint(i))
FindPaths(v.Index(i), targetType, newPath, paths)
if v.Index(i).Type() == targetType {
*paths = append(*paths, strings.Join(newPath, "."))
}
}
case reflect.String:
if vType != targetType {
return
}
default:
return
}
if vType == targetType {
*paths = append(*paths, strings.Join(path, "."))
}
}
package pathfinder
import (
"reflect"
"testing"
)
type TestStruct struct {
Field1 string
Field2 int
Inner struct {
SubField1 float64
SubField2 string
}
}
func TestFindPaths(t *testing.T) {
tests := []struct {
input interface{}
targetType reflect.Type
expectedPaths []string
}{
{
TestStruct{"hello", 42, struct {
SubField1 float64
SubField2 string
}{3.14, "world"}},
reflect.TypeOf(""),
[]string{"Field1", "Inner.SubField2"},
},
{
[]int{1, 2, 3},
reflect.TypeOf(0),
[]string{"0", "1", "2"},
},
{
map[string]int{"key1": 1, "key2": 2},
reflect.TypeOf(0),
[]string{"key1", "key2"},
},
{
nil,
reflect.TypeOf(""),
[]string{},
},
}
for i, test := range tests {
var paths []string
FindPaths(reflect.ValueOf(test.input), test.targetType, []string{}, &paths)
if len(paths) == 0 && len(test.expectedPaths) == 0 {
continue
}
if !reflect.DeepEqual(paths, test.expectedPaths) {
t.Errorf("Test case %d failed, expected %v, got %v", i+1, test.expectedPaths, paths)
}
}
}
package pathfinder
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