From c768f8a00132ef66c9b020e13eb156f53619fbbb Mon Sep 17 00:00:00 2001
From: Volker Schukai <volker.schukai@schukai.com>
Date: Sat, 16 Sep 2023 16:53:32 +0200
Subject: [PATCH] fix: set interface do not work #14

---
 issue_14_test.go | 27 ++++++++++++++++++++++--
 set.go           | 53 +++++++-----------------------------------------
 2 files changed, 32 insertions(+), 48 deletions(-)

diff --git a/issue_14_test.go b/issue_14_test.go
index 66bab07..52c0cd3 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 92b6509..5981594 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:
-- 
GitLab