Skip to content

Commit

Permalink
Merge pull request #40 from remrain/vd-tag-recursion-optmized
Browse files Browse the repository at this point in the history
findVdTag() recursion optmized
  • Loading branch information
andeya authored Jan 26, 2022
2 parents 7d572be + 68bc7ad commit 59f6de6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
11 changes: 6 additions & 5 deletions binding/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ func (b *Binding) getOrPrepareReceiver(value reflect.Value) (*receiver, error) {
return nil, b.bindErrFactory(errExprSelector.String(), errMsg)
}
if !recv.hasVd {
recv.hasVd, _ = b.findVdTag(ameda.DereferenceType(t), false, 20)
recv.hasVd, _ = b.findVdTag(ameda.DereferenceType(t), false, 20, map[reflect.Type]bool{})
}
recv.initParams()

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

func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int) (hasVd bool, err error) {
if depth <= 0 {
func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int, exist map[reflect.Type]bool) (hasVd bool, err error) {
if depth <= 0 || exist[t] {
return
}
depth--
switch t.Kind() {
case reflect.Struct:
exist[t] = true
for i := t.NumField() - 1; i >= 0; i-- {
field := t.Field(i)
if inMapOrSlice {
Expand All @@ -400,14 +401,14 @@ func (b *Binding) findVdTag(t reflect.Type, inMapOrSlice bool, depth int) (hasVd
}
}
}
hasVd, _ = b.findVdTag(ameda.DereferenceType(field.Type), inMapOrSlice, depth)
hasVd, _ = b.findVdTag(ameda.DereferenceType(field.Type), inMapOrSlice, depth, exist)
if hasVd {
return true, nil
}
}
return false, nil
case reflect.Slice, reflect.Array, reflect.Map:
return b.findVdTag(ameda.DereferenceType(t.Elem()), true, depth)
return b.findVdTag(ameda.DereferenceType(t.Elem()), true, depth, exist)
default:
return false, nil
}
Expand Down
15 changes: 15 additions & 0 deletions binding/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,3 +1181,18 @@ func TestDefault2(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "hello Dash", (**recv.X).Dash)
}

func TestVdTagRecursion(t *testing.T) {
type Node struct {
N1 *Node
N2 *Node
N3 *Node
}
recv := &Node{}
req, _ := http.NewRequest("get", "http://localhost/", bytes.NewReader([]byte{}))
start := time.Now()
binder := binding.New(nil)
err := binder.BindAndValidate(recv, req, new(testPathParams2))
assert.NoError(t, err)
assert.Less(t, int64(time.Since(start)), int64(time.Second))
}

0 comments on commit 59f6de6

Please sign in to comment.