Skip to content

Commit

Permalink
Inserting data into any type
Browse files Browse the repository at this point in the history
  • Loading branch information
mowshon committed Apr 22, 2024
1 parent 76fc362 commit 3541fa8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
8 changes: 7 additions & 1 deletion dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ func (d *Dot) insert(innerObj reflect.Value, previousPath string, parts []string
if innerObj.Kind() == reflect.Chan {
return d.inChannel(innerObj, currentPath, remainingParts)
}
case reflect.Interface:
return fmt.Errorf(
"the type in %s is interface{} and it is impossible to further predict the path",
previousPath,
)

default:
// If it is logical to already insert a value in the specified path,
// but the path has not yet ended, it means that the path is specified incorrectly
Expand All @@ -140,7 +146,7 @@ func set(innerObj reflect.Value, currentPath string, content any, source Scenari
value := reflect.ValueOf(content)

// Checking for type matching
if innerObj.Type() != value.Type() {
if innerObj.Type() != value.Type() && innerObj.Kind() != reflect.Interface {
return fmt.Errorf(
errMsg[source], innerObj.Type(), value.Type(), currentPath,
)
Expand Down
30 changes: 30 additions & 0 deletions dot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type Data struct {
K map[uint64]string
L map[Key]string
M map[[2]int]string
N map[string]any
}

func TestInvalidType(t *testing.T) {
Expand Down Expand Up @@ -76,6 +77,35 @@ func TestNewFailure(t *testing.T) {
}
}

func TestSetInterface(t *testing.T) {
data := Data{
N: map[string]any{
"First": Info{},
},
}

obj, err := dot.New(&data)
assert.Nil(t, err)

// On the path of data insertion the type interface{} is found,
// further it is impossible to define the path
if err := obj.Insert("N.First.Title", "New Title"); assert.Error(t, err) {
assert.ErrorContains(
t, err, "the type in N.First is interface{} and it is impossible to further predict the path",
)
}

// If the final destination in the path is interface{},
// then we insert the provided value into it
if err := obj.Insert("N.First", Info{Title: "Any Title"}); assert.NoError(t, err) {
if value, exists := data.N["First"]; assert.True(t, exists) {
if n, ok := value.(Info); assert.True(t, ok) {
assert.Exactly(t, "Any Title", n.Title)
}
}
}
}

func TestUnknownPlaceholder(t *testing.T) {
data := Data{}
obj, err := dot.New(&data)
Expand Down

0 comments on commit 3541fa8

Please sign in to comment.