diff --git a/issue_14_test.go b/issue_14_test.go index 66bab07a51e5a59a9742253ec05178d55bace509..52c0cd31595c90b0110a41bb9ae4a9b782d190a8 100644 --- a/issue_14_test.go +++ b/issue_14_test.go @@ -1,9 +1,32 @@ package pathfinder import ( + "github.com/stretchr/testify/assert" "testing" ) -func TestPathFindSetValueFrom14(t *testing.T) { - +type DeepNestedStruct struct { + A PathValue +} + +type MyStruct struct { + I map[string]DeepNestedStruct +} + +func TestReplacePath(t *testing.T) { + // Sample seed data to guide the fuzzer + + s := &MyStruct{ + I: map[string]DeepNestedStruct{ + "key1GI": { + A: "rel/pathGIA", + }, + }, + } + + err := SetValue[*MyStruct](s, "I.key1GI.A", "new/pathGIA") + assert.Nil(t, err) + + assert.Equal(t, PathValue("new/pathGIA"), s.I["key1GI"].A) + } diff --git a/set.go b/set.go index 92b650947c7d46f0ff6bd197ac59662db76dd130..598159453d542c739e9e2d1f6e5f1dfbbe4ec098 100644 --- a/set.go +++ b/set.go @@ -51,6 +51,7 @@ func SetValue[D any](obj D, keyWithDots string, newValue any) error { return newCannotSetError("Wert ist nicht adressierbar") } newKey := strings.Join(keySlice[keyIndex+1:], ".") + err := SetValue(newValueCopyPtr, newKey, newValue) if err != nil { return err @@ -146,58 +147,13 @@ func SetValue[D any](obj D, keyWithDots string, newValue any) error { m.SetMapIndex(keyValConverted, newValConverted) return nil - //currentValue := reflectionOfObject.MapIndex(reflect.ValueOf(key)).Interface() - //newValueCopy := reflect.New(reflect.TypeOf(currentValue)).Interface() - //if err := deepCopy(currentValue, newValueCopy); err != nil { - // return err - //} - //newValueCopyPtr := &newValueCopy - //newValueCopyReflect := reflect.ValueOf(newValueCopyPtr).Elem() - //if !newValueCopyReflect.CanAddr() { - // return newCannotSetError("Wert ist nicht adressierbar") - //} - ////newKey := strings.Join(keySlice[keyIndex+1:], ".") - ////err := SetValue(newValueCopyPtr, newKey, newValue) - ////if err != nil { - //// return err - ////} - // - //reflectionOfObject.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(newValueCopy).Elem()) - //return nil - - //if reflectionOfObject.IsNil() { - // return newInvalidPathError(keyWithDots) - //} - // - //index := keySlice[len(keySlice)-1] - //reflectedIndex := reflect.ValueOf(index) - // - //if !reflectedIndex.Type().AssignableTo(reflectionOfObject.Type().Key()) { - // return newInvalidPathError(keyWithDots) - //} - // - //currentValue := reflectionOfObject.MapIndex(reflectedIndex).Interface() - //newValueCopy := reflect.New(reflect.TypeOf(currentValue)).Interface() - //if err := deepCopy(currentValue, newValueCopy); err != nil { - // return err - //} - // - //if !reflect.ValueOf(newValueCopy).Elem().Type().AssignableTo(reflectionOfObject.Type().Elem()) { - // return newInvalidPathError(keyWithDots) - //} - // - //newValueCopyX := reflect.ValueOf(newValueCopy).Elem() - //reflectionOfObject.SetMapIndex(reflectedIndex, newValueCopyX) - case reflect.Slice: - // index is a number and get reflectionOfObject from slice with index index, err := strconv.Atoi(keySlice[len(keySlice)-1]) if err != nil { return newInvalidPathError(keyWithDots) } - // index out of range if index >= reflectionOfObject.Len() { return newInvalidPathError(keyWithDots) } @@ -214,7 +170,12 @@ func SetValue[D any](obj D, keyWithDots string, newValue any) error { } return nil case reflect.Interface: - return newUnsupportedTypeAtTopOfPathError(keyWithDots, reflectionOfObject.Type()) + + // check if reflectionOfObject is an interface to an struct pointer + if reflectionOfObject.Elem().Kind() == reflect.Ptr && reflectionOfObject.Elem().Elem().Kind() == reflect.Struct { + return SetValue(reflectionOfObject.Elem().Interface(), keySlice[len(keySlice)-1], newValue) + } + case reflect.Chan: return newUnsupportedTypeAtTopOfPathError(keyWithDots, reflectionOfObject.Type()) case reflect.Func: