Skip to content

Commit f9b6d05

Browse files
committed
refactor(binding): rm redundant code and perf
1 parent 95440fa commit f9b6d05

36 files changed

+1968
-2044
lines changed

go.mod

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ require (
1010
github.com/fsnotify/fsnotify v1.5.4
1111
github.com/nyaruka/phonenumbers v1.0.55
1212
github.com/stretchr/testify v1.8.1
13-
github.com/tidwall/gjson v1.14.4
1413
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
1514
golang.org/x/sys v0.24.0
1615
google.golang.org/protobuf v1.27.1
@@ -28,8 +27,6 @@ require (
2827
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
2928
github.com/smartystreets/goconvey v1.6.4 // indirect
3029
github.com/stretchr/objx v0.5.0 // indirect
31-
github.com/tidwall/match v1.1.1 // indirect
32-
github.com/tidwall/pretty v1.2.0 // indirect
3330
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
3431
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
3532
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
4646
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
4747
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
4848
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
49-
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
50-
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
51-
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
52-
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
53-
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
54-
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
5549
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
5650
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
57-
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
5851
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
5952
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
6053
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -84,4 +77,3 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
8477
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
8578
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
8679
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
87-
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

pkg/app/server/binding/binder_test.go

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ func TestBind_RequiredBind(t *testing.T) {
468468
req := newMockRequest().
469469
SetRequestURI("http://foobar.com")
470470
err := DefaultBinder().Bind(req.Req, &s, nil)
471-
assert.DeepEqual(t, "'a' field is a 'required' parameter, but the request does not have this parameter", err.Error())
471+
assert.DeepEqual(t, `decode field "A" err: field is required, but not set`, err.Error())
472472

473473
req = newMockRequest().
474474
SetRequestURI("http://foobar.com").
@@ -617,9 +617,7 @@ func TestBind_JSON(t *testing.T) {
617617
SetBody([]byte(fmt.Sprintf(`{"j1":"j1", "j2":12, "j3":[%d, %d], "j4":["%s", "%s"]}`, J3s[0], J3s[1], J4s[0], J4s[1])))
618618
var result Req
619619
err := DefaultBinder().Bind(req.Req, &result, nil)
620-
if err != nil {
621-
t.Error(err)
622-
}
620+
assert.Nil(t, err)
623621
assert.DeepEqual(t, "j1", result.J1)
624622
assert.DeepEqual(t, 13, result.J2)
625623
for idx, val := range J3s {
@@ -931,9 +929,9 @@ func TestBind_JSONRequiredField(t *testing.T) {
931929
var result Req
932930
err := DefaultBinder().Bind(req.Req, &result, nil)
933931
if err == nil {
934-
t.Errorf("expected an error, but get nil")
932+
t.Fatal("expected an error, but get nil")
935933
}
936-
assert.DeepEqual(t, "'c' field is a 'required' parameter, but the request body does not have this parameter 'n.n2.c'", err.Error())
934+
assert.DeepEqual(t, `decode field "N" err: decode field "N2" err: decode field "C" err: JSON field "n.n2.c" is required, but it's not set`, err.Error())
937935
assert.DeepEqual(t, 1, result.N.A)
938936
assert.DeepEqual(t, 2, result.N.B)
939937
assert.DeepEqual(t, 0, result.N.N2.C)
@@ -1259,18 +1257,14 @@ func TestBind_PointerStruct(t *testing.T) {
12591257
SetRequestURI(fmt.Sprintf("http://foobar.com?%s", query.Encode()))
12601258

12611259
err := binder.Bind(req.Req, &result, nil)
1262-
if err != nil {
1263-
t.Error(err)
1264-
}
1260+
assert.Nil(t, err)
12651261
assert.DeepEqual(t, "111", (**result.B1).F1)
12661262

12671263
result = Bar{}
12681264
req = newMockRequest().
12691265
SetRequestURI(fmt.Sprintf("http://foobar.com?%s&F1=222", query.Encode()))
12701266
err = binder.Bind(req.Req, &result, nil)
1271-
if err != nil {
1272-
t.Error(err)
1273-
}
1267+
assert.Nil(t, err)
12741268
assert.DeepEqual(t, "222", (**result.B1).F1)
12751269
}
12761270

@@ -1522,7 +1516,7 @@ func Test_ValidatorErrorFactory(t *testing.T) {
15221516
if err == nil {
15231517
t.Fatalf("unexpected nil, expected an error")
15241518
}
1525-
assert.DeepEqual(t, "'a' field is a 'required' parameter, but the request does not have this parameter", err.Error())
1519+
assert.DeepEqual(t, `decode field "A" err: field is required, but not set`, err.Error())
15261520

15271521
type TestValidate struct {
15281522
B int `query:"b" vd:"$>100"`
@@ -1617,9 +1611,7 @@ func TestBind_JSONWithDefault(t *testing.T) {
16171611
SetJSONContentType().
16181612
SetBody([]byte(`{"j2":"j2"}`))
16191613
err = DefaultBinder().Bind(req.Req, &result, nil)
1620-
if err != nil {
1621-
t.Error(err)
1622-
}
1614+
assert.Nil(t, err)
16231615
assert.DeepEqual(t, "j1default", result.J1)
16241616
}
16251617

@@ -1637,9 +1629,7 @@ func TestBind_WithoutPreBindForTag(t *testing.T) {
16371629
var result BaseQuery
16381630

16391631
err := DefaultBinder().BindQuery(req.Req, &result)
1640-
if err != nil {
1641-
t.Error(err)
1642-
}
1632+
assert.Nil(t, err)
16431633
assert.DeepEqual(t, "action", result.Action)
16441634
assert.DeepEqual(t, "version", result.Version)
16451635
}
@@ -1686,9 +1676,10 @@ func Benchmark_Binding(b *testing.B) {
16861676
})
16871677

16881678
b.ResetTimer()
1679+
result := &Req{}
16891680
for i := 0; i < b.N; i++ {
1690-
var result Req
1691-
err := DefaultBinder().Bind(req.Req, &result, params)
1681+
*result = Req{}
1682+
err := DefaultBinder().Bind(req.Req, result, params)
16921683
if err != nil {
16931684
b.Error(err)
16941685
}

pkg/app/server/binding/config.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ type BindConfig struct {
6666
// TypeUnmarshalFuncs registers customized type unmarshaler.
6767
// NOTE:
6868
// time.Time is registered by default
69-
TypeUnmarshalFuncs map[reflect.Type]inDecoder.CustomizeDecodeFunc
69+
TypeUnmarshalFuncs map[reflect.Type]inDecoder.CustomDecodeFunc
7070
// Validator is used to validate for BindAndValidate()
7171
Validator StructValidator
7272
}
@@ -78,13 +78,13 @@ func NewBindConfig() *BindConfig {
7878
DisableStructFieldResolve: false,
7979
EnableDecoderUseNumber: false,
8080
EnableDecoderDisallowUnknownFields: false,
81-
TypeUnmarshalFuncs: make(map[reflect.Type]inDecoder.CustomizeDecodeFunc),
81+
TypeUnmarshalFuncs: make(map[reflect.Type]inDecoder.CustomDecodeFunc),
8282
Validator: defaultValidate,
8383
}
8484
}
8585

8686
// RegTypeUnmarshal registers customized type unmarshaler.
87-
func (config *BindConfig) RegTypeUnmarshal(t reflect.Type, fn inDecoder.CustomizeDecodeFunc) error {
87+
func (config *BindConfig) RegTypeUnmarshal(t reflect.Type, fn inDecoder.CustomDecodeFunc) error {
8888
// check
8989
switch t.Kind() {
9090
case reflect.String, reflect.Bool,
@@ -96,7 +96,7 @@ func (config *BindConfig) RegTypeUnmarshal(t reflect.Type, fn inDecoder.Customiz
9696
return fmt.Errorf("registration type cannot be a pointer type")
9797
}
9898
if config.TypeUnmarshalFuncs == nil {
99-
config.TypeUnmarshalFuncs = make(map[reflect.Type]inDecoder.CustomizeDecodeFunc)
99+
config.TypeUnmarshalFuncs = make(map[reflect.Type]inDecoder.CustomDecodeFunc)
100100
}
101101
config.TypeUnmarshalFuncs[t] = fn
102102
return nil

pkg/app/server/binding/default.go

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ type decoderInfo struct {
9494
needValidate bool
9595
}
9696

97+
func (d *decoderInfo) Decode(req *protocol.Request, params param.Params, rv reflect.Value) error {
98+
_, err := d.decoder.Decode(req, params, rv)
99+
return err
100+
}
101+
97102
var defaultBind = NewDefaultBinder(nil)
98103

99104
func DefaultBinder() Binder {
@@ -187,28 +192,29 @@ func (b *defaultBinder) bindTag(req *protocol.Request, v interface{}, params par
187192
if ok {
188193
// cached fieldDecoder, fast path
189194
decoder := cached.(decoderInfo)
190-
return decoder.decoder(req, params, rv.Elem())
195+
return decoder.Decode(req, params, rv.Elem())
191196
}
192197
validateTag := defaultValidateTag
193198
if len(b.config.Validator.ValidateTag()) != 0 {
194199
validateTag = b.config.Validator.ValidateTag()
195200
}
196201
decodeConfig := &inDecoder.DecodeConfig{
197-
LooseZeroMode: b.config.LooseZeroMode,
198-
DisableDefaultTag: b.config.DisableDefaultTag,
199-
DisableStructFieldResolve: b.config.DisableStructFieldResolve,
200-
EnableDecoderUseNumber: b.config.EnableDecoderUseNumber,
201-
EnableDecoderDisallowUnknownFields: b.config.EnableDecoderDisallowUnknownFields,
202-
ValidateTag: validateTag,
203-
TypeUnmarshalFuncs: b.config.TypeUnmarshalFuncs,
204-
}
205-
decoder, needValidate, err := inDecoder.GetReqDecoder(rv.Type(), tag, decodeConfig)
202+
LooseZeroMode: b.config.LooseZeroMode,
203+
DisableDefaultTag: b.config.DisableDefaultTag,
204+
DisableStructFieldResolve: b.config.DisableStructFieldResolve,
205+
TypeUnmarshalFuncs: b.config.TypeUnmarshalFuncs,
206+
DecodeTag: tag,
207+
}
208+
decoder, err := inDecoder.NewDecoder(rv.Type(), decodeConfig)
206209
if err != nil {
207210
return err
208211
}
209-
210-
cache.Store(typeID, decoderInfo{decoder: decoder, needValidate: needValidate})
211-
return decoder(req, params, rv.Elem())
212+
cache.Store(typeID, decoderInfo{
213+
decoder: decoder,
214+
needValidate: containsStructTag(rv.Type(), validateTag, nil),
215+
})
216+
_, err = decoder.Decode(req, params, rv.Elem())
217+
return err
212218
}
213219

214220
func (b *defaultBinder) bindTagWithValidate(req *protocol.Request, v interface{}, params param.Params, tag string) error {
@@ -230,7 +236,7 @@ func (b *defaultBinder) bindTagWithValidate(req *protocol.Request, v interface{}
230236
if ok {
231237
// cached fieldDecoder, fast path
232238
decoder := cached.(decoderInfo)
233-
err = decoder.decoder(req, params, rv.Elem())
239+
err = decoder.Decode(req, params, rv.Elem())
234240
if err != nil {
235241
return err
236242
}
@@ -244,21 +250,19 @@ func (b *defaultBinder) bindTagWithValidate(req *protocol.Request, v interface{}
244250
validateTag = b.config.Validator.ValidateTag()
245251
}
246252
decodeConfig := &inDecoder.DecodeConfig{
247-
LooseZeroMode: b.config.LooseZeroMode,
248-
DisableDefaultTag: b.config.DisableDefaultTag,
249-
DisableStructFieldResolve: b.config.DisableStructFieldResolve,
250-
EnableDecoderUseNumber: b.config.EnableDecoderUseNumber,
251-
EnableDecoderDisallowUnknownFields: b.config.EnableDecoderDisallowUnknownFields,
252-
ValidateTag: validateTag,
253-
TypeUnmarshalFuncs: b.config.TypeUnmarshalFuncs,
254-
}
255-
decoder, needValidate, err := inDecoder.GetReqDecoder(rv.Type(), tag, decodeConfig)
253+
LooseZeroMode: b.config.LooseZeroMode,
254+
DisableDefaultTag: b.config.DisableDefaultTag,
255+
DisableStructFieldResolve: b.config.DisableStructFieldResolve,
256+
TypeUnmarshalFuncs: b.config.TypeUnmarshalFuncs,
257+
DecodeTag: tag,
258+
}
259+
decoder, err := inDecoder.NewDecoder(rv.Type(), decodeConfig)
256260
if err != nil {
257261
return err
258262
}
259-
263+
needValidate := containsStructTag(rv.Type(), validateTag, nil)
260264
cache.Store(typeID, decoderInfo{decoder: decoder, needValidate: needValidate})
261-
err = decoder(req, params, rv.Elem())
265+
_, err = decoder.Decode(req, params, rv.Elem())
262266
if err != nil {
263267
return err
264268
}

0 commit comments

Comments
 (0)