Skip to content

Commit 59f6de6

Browse files
authored
Merge pull request #40 from remrain/vd-tag-recursion-optmized
findVdTag() recursion optmized
2 parents 7d572be + 68bc7ad commit 59f6de6

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

binding/bind.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ func (b *Binding) getOrPrepareReceiver(value reflect.Value) (*receiver, error) {
372372
return nil, b.bindErrFactory(errExprSelector.String(), errMsg)
373373
}
374374
if !recv.hasVd {
375-
recv.hasVd, _ = b.findVdTag(ameda.DereferenceType(t), false, 20)
375+
recv.hasVd, _ = b.findVdTag(ameda.DereferenceType(t), false, 20, map[reflect.Type]bool{})
376376
}
377377
recv.initParams()
378378

@@ -383,13 +383,14 @@ func (b *Binding) getOrPrepareReceiver(value reflect.Value) (*receiver, error) {
383383
return recv, nil
384384
}
385385

386-
func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int) (hasVd bool, err error) {
387-
if depth <= 0 {
386+
func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int, exist map[reflect.Type]bool) (hasVd bool, err error) {
387+
if depth <= 0 || exist[t] {
388388
return
389389
}
390390
depth--
391391
switch t.Kind() {
392392
case reflect.Struct:
393+
exist[t] = true
393394
for i := t.NumField() - 1; i >= 0; i-- {
394395
field := t.Field(i)
395396
if inMapOrSlice {
@@ -400,14 +401,14 @@ func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int) (hasVd
400401
}
401402
}
402403
}
403-
hasVd, _ = b.findVdTag(ameda.DereferenceType(field.Type), inMapOrSlice, depth)
404+
hasVd, _ = b.findVdTag(ameda.DereferenceType(field.Type), inMapOrSlice, depth, exist)
404405
if hasVd {
405406
return true, nil
406407
}
407408
}
408409
return false, nil
409410
case reflect.Slice, reflect.Array, reflect.Map:
410-
return b.findVdTag(ameda.DereferenceType(t.Elem()), true, depth)
411+
return b.findVdTag(ameda.DereferenceType(t.Elem()), true, depth, exist)
411412
default:
412413
return false, nil
413414
}

binding/bind_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -1181,3 +1181,18 @@ func TestDefault2(t *testing.T) {
11811181
assert.NoError(t, err)
11821182
assert.Equal(t, "hello Dash", (**recv.X).Dash)
11831183
}
1184+
1185+
func TestVdTagRecursion(t *testing.T) {
1186+
type Node struct {
1187+
N1 *Node
1188+
N2 *Node
1189+
N3 *Node
1190+
}
1191+
recv := &Node{}
1192+
req, _ := http.NewRequest("get", "http://localhost/", bytes.NewReader([]byte{}))
1193+
start := time.Now()
1194+
binder := binding.New(nil)
1195+
err := binder.BindAndValidate(recv, req, new(testPathParams2))
1196+
assert.NoError(t, err)
1197+
assert.Less(t, int64(time.Since(start)), int64(time.Second))
1198+
}

0 commit comments

Comments
 (0)