Skip to content

Commit 69cb27c

Browse files
committed
primitive types handling
1 parent fe56b7d commit 69cb27c

File tree

2 files changed

+83
-15
lines changed

2 files changed

+83
-15
lines changed

resolver/resolver_test.go

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package resolver
22

33
import (
4+
"net"
45
"reflect"
56
"testing"
67
"time"
@@ -67,20 +68,14 @@ func Test_resolveValue(t *testing.T) {
6768
}
6869

6970
func Test_resolve(t *testing.T) {
70-
resolver := NewDefaultValueResolver(
71-
WithCustomTypes(
72-
NewValueResolverTime(time.RFC3339),
73-
NewValueResolverTimeDuration(),
74-
),
75-
)
71+
resolver := NewDefaultValueResolver()
7672

7773
type CustomType struct {
7874
X int
7975
}
8076

8177
type CustomTypeSub CustomType
8278

83-
t1, _ := time.Parse(time.RFC3339, "2021-10-22T11:01:00Z")
8479
tests := []struct {
8580
name string
8681
input interface{}
@@ -91,9 +86,7 @@ func Test_resolve(t *testing.T) {
9186
{name: "resolve string", input: string(""), value: "test", want: "test", wantErr: false},
9287
{name: "resolve bool", input: bool(false), value: "true", want: true, wantErr: false},
9388
{name: "resolve failed bool", input: bool(false), value: "trick", want: bool(false), wantErr: true},
94-
{name: "resolve time", input: time.Time{}, value: "2021-10-22T11:01:00Z", want: t1, wantErr: false},
9589
{name: "resolve failed time", input: time.Time{}, value: "trick", want: time.Time{}, wantErr: true},
96-
{name: "resolve duration", input: time.Duration(0), value: "5s", want: 5 * time.Second, wantErr: false},
9790
{name: "resolve failed duration", input: time.Duration(0), value: "trick", want: time.Duration(0), wantErr: true},
9891
{name: "resolve int", input: int(0), value: "5", want: int(5), wantErr: false},
9992
{name: "resolve failed int", input: int(0), value: "trick", want: int(0), wantErr: true},
@@ -119,8 +112,9 @@ func Test_resolve(t *testing.T) {
119112
{name: "resolve failed uint16", input: uint16(0), value: "trick", want: uint16(0), wantErr: true},
120113
{name: "resolve uint8", input: uint8(0), value: "5", want: uint8(5), wantErr: false},
121114
{name: "resolve failed uint8", input: uint8(0), value: "trick", want: uint8(0), wantErr: true},
122-
{name: "custom type", input: CustomType{}, value: CustomType{5}, want: CustomType{5}, wantErr: false},
115+
{name: "custom type assignable", input: CustomType{}, value: CustomType{5}, want: CustomType{5}, wantErr: false},
123116
{name: "custom type convertible", input: CustomTypeSub{}, value: CustomType{5}, want: CustomTypeSub{5}, wantErr: false},
117+
{name: "custom type based on primitive", input: net.IP{}, value: []byte{1, 2, 3, 4}, want: net.IP{}, wantErr: true},
124118
{name: "failed unsupported type", input: []struct{}{}, value: "trick", want: nil, wantErr: true},
125119
}
126120
for i := range tests {
@@ -140,6 +134,53 @@ func Test_resolve(t *testing.T) {
140134
}
141135
}
142136

137+
func Test_resolve_customTypes(t *testing.T) {
138+
resolver := NewDefaultValueResolver(
139+
WithCustomTypes(
140+
NewValueResolverTime(time.RFC3339),
141+
NewValueResolverTimeDuration(),
142+
),
143+
)
144+
145+
type CustomType struct {
146+
X int
147+
}
148+
149+
type CustomTypeSub CustomType
150+
151+
t1, _ := time.Parse(time.RFC3339, "2021-10-22T11:01:00Z")
152+
tests := []struct {
153+
name string
154+
input interface{}
155+
value any
156+
want interface{}
157+
wantErr bool
158+
}{
159+
{name: "resolve time", input: time.Time{}, value: "2021-10-22T11:01:00Z", want: t1, wantErr: false},
160+
{name: "resolve failed time", input: time.Time{}, value: "trick", want: time.Time{}, wantErr: true},
161+
{name: "resolve duration", input: time.Duration(0), value: "5s", want: 5 * time.Second, wantErr: false},
162+
{name: "resolve failed duration", input: time.Duration(0), value: "trick", want: time.Duration(0), wantErr: true},
163+
{name: "custom type", input: CustomType{}, value: CustomType{5}, want: CustomType{5}, wantErr: false},
164+
{name: "custom type convertible", input: CustomTypeSub{}, value: CustomType{5}, want: CustomTypeSub{5}, wantErr: false},
165+
{name: "custom type based on primitive", input: net.IP{}, value: []byte{1, 2, 3, 4}, want: net.IP{}, wantErr: true},
166+
}
167+
for i := range tests {
168+
tt := tests[i]
169+
t.Run(tt.name, func(t *testing.T) {
170+
target := reflect.Indirect(reflect.New(reflect.TypeOf(tt.input)))
171+
target.Set(reflect.ValueOf(tt.input))
172+
err := resolver.ResolveValue(target, tt.value)
173+
if (err != nil) != tt.wantErr {
174+
t.Errorf("resolve() error = %v, wantErr %v", err, tt.wantErr)
175+
return
176+
}
177+
if err == nil {
178+
require.Equal(t, tt.want, target.Interface())
179+
}
180+
})
181+
}
182+
}
183+
143184
func Test_resolve_textUnmarshaller(t *testing.T) {
144185
resolver := NewDefaultValueResolver(
145186
WithCustomTypesReflect(
@@ -148,9 +189,35 @@ func Test_resolve_textUnmarshaller(t *testing.T) {
148189
)
149190

150191
t1, _ := time.Parse(time.RFC3339, "2021-10-22T11:01:00Z")
192+
tests := []struct {
193+
name string
194+
input interface{}
195+
value any
196+
want interface{}
197+
wantErr bool
198+
}{
199+
{name: "resolve time", input: time.Time{}, value: "2021-10-22T11:01:00Z", want: t1, wantErr: false},
200+
{name: "resolve failed time", input: time.Time{}, value: "trick", want: time.Time{}, wantErr: true},
201+
{name: "custom type based on primitive", input: net.IP{}, value: "1.2.3.4", want: net.IP{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x1, 0x2, 0x3, 0x4}, wantErr: false},
202+
}
203+
for i := range tests {
204+
tt := tests[i]
205+
t.Run(tt.name, func(t *testing.T) {
206+
target := reflect.Indirect(reflect.New(reflect.TypeOf(tt.input)))
207+
target.Set(reflect.ValueOf(tt.input))
208+
err := resolver.ResolveValue(target, tt.value)
209+
if (err != nil) != tt.wantErr {
210+
t.Errorf("resolve() error = %v, wantErr %v", err, tt.wantErr)
211+
return
212+
}
213+
if err == nil {
214+
require.Equal(t, tt.want, target.Interface())
215+
}
216+
})
217+
}
151218

152-
target := reflect.Indirect(reflect.New(reflect.TypeOf(time.Time{})))
153-
err := resolver.ResolveValue(target, "2021-10-22T11:01:00Z")
154-
require.NoError(t, err)
155-
require.Equal(t, t1, target.Interface())
219+
// target := reflect.Indirect(reflect.New(reflect.TypeOf(time.Time{})))
220+
// err := resolver.ResolveValue(target, "2021-10-22T11:01:00Z")
221+
// require.NoError(t, err)
222+
// require.Equal(t, t1, target.Interface())
156223
}

resolver/resolver_value.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ func (r DefaultValueResolver) resolveValue(target reflect.Value, value any) erro
179179

180180
// check if types are directly assignable
181181

182-
if target.Type().AssignableTo(sourceValue.Type()) {
182+
if target.Type() == sourceValue.Type() ||
183+
(target.Type().AssignableTo(sourceValue.Type()) && target.Type().Kind() != reflect.Slice) {
183184
// the source can be directly assigned to the target
184185
target.Set(sourceValue)
185186
return nil

0 commit comments

Comments
 (0)