Skip to content

Commit c1a2bb3

Browse files
author
ganlei
committed
feat: support user use specify tag
1 parent 3455b53 commit c1a2bb3

File tree

2 files changed

+40
-29
lines changed

2 files changed

+40
-29
lines changed

query/encode.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ type Encoder interface {
123123
//
124124
// Multiple fields that encode to the same URL parameter name will be included
125125
// as multiple URL values of the same name.
126-
func Values(v interface{}) (url.Values, error) {
126+
func Values(userTag string, v interface{}) (url.Values, error) {
127+
if userTag == "" {
128+
userTag = "url" // default tag
129+
}
127130
values := make(url.Values)
128131
val := reflect.ValueOf(v)
129132
for val.Kind() == reflect.Ptr {
@@ -141,14 +144,14 @@ func Values(v interface{}) (url.Values, error) {
141144
return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind())
142145
}
143146

144-
err := reflectValue(values, val, "")
147+
err := reflectValue(userTag, values, val, "")
145148
return values, err
146149
}
147150

148151
// reflectValue populates the values parameter from the struct fields in val.
149152
// Embedded structs are followed recursively (using the rules defined in the
150153
// Values function documentation) breadth-first.
151-
func reflectValue(values url.Values, val reflect.Value, scope string) error {
154+
func reflectValue(userTag string, values url.Values, val reflect.Value, scope string) error {
152155
var embedded []reflect.Value
153156

154157
typ := val.Type()
@@ -159,7 +162,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
159162
}
160163

161164
sv := val.Field(i)
162-
tag := sf.Tag.Get("url")
165+
tag := sf.Tag.Get(userTag)
163166
if tag == "-" {
164167
continue
165168
}
@@ -257,7 +260,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
257260
}
258261

259262
if sv.Kind() == reflect.Struct {
260-
if err := reflectValue(values, sv, name); err != nil {
263+
if err := reflectValue(userTag, values, sv, name); err != nil {
261264
return err
262265
}
263266
continue
@@ -267,7 +270,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
267270
}
268271

269272
for _, f := range embedded {
270-
if err := reflectValue(values, f, scope); err != nil {
273+
if err := reflectValue(userTag, values, f, scope); err != nil {
271274
return err
272275
}
273276
}

query/encode_test.go

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import (
1616
)
1717

1818
// test that Values(input) matches want. If not, report an error on t.
19-
func testValue(t *testing.T, input interface{}, want url.Values) {
20-
v, err := Values(input)
19+
func testValue(t *testing.T, userTag string, input interface{}, want url.Values) {
20+
v, err := Values(userTag, input)
2121
if err != nil {
2222
t.Errorf("Values(%q) returned error: %v", input, err)
2323
}
@@ -28,31 +28,34 @@ func testValue(t *testing.T, input interface{}, want url.Values) {
2828

2929
func TestValues_BasicTypes(t *testing.T) {
3030
tests := []struct {
31+
myTag string
3132
input interface{}
3233
want url.Values
3334
}{
3435
// zero values
35-
{struct{ V string }{}, url.Values{"V": {""}}},
36-
{struct{ V int }{}, url.Values{"V": {"0"}}},
37-
{struct{ V uint }{}, url.Values{"V": {"0"}}},
38-
{struct{ V float32 }{}, url.Values{"V": {"0"}}},
39-
{struct{ V bool }{}, url.Values{"V": {"false"}}},
36+
{"userTag", struct{ V string }{}, url.Values{"V": {""}}},
37+
{"userTag", struct{ V int }{}, url.Values{"V": {"0"}}},
38+
{"userTag", struct{ V uint }{}, url.Values{"V": {"0"}}},
39+
{"userTag", struct{ V float32 }{}, url.Values{"V": {"0"}}},
40+
{"userTag", struct{ V bool }{}, url.Values{"V": {"false"}}},
4041

4142
// simple non-zero values
42-
{struct{ V string }{"v"}, url.Values{"V": {"v"}}},
43-
{struct{ V int }{1}, url.Values{"V": {"1"}}},
44-
{struct{ V uint }{1}, url.Values{"V": {"1"}}},
45-
{struct{ V float32 }{0.1}, url.Values{"V": {"0.1"}}},
46-
{struct{ V bool }{true}, url.Values{"V": {"true"}}},
43+
{"userTag", struct{ V string }{"v"}, url.Values{"V": {"v"}}},
44+
{"userTag", struct{ V int }{1}, url.Values{"V": {"1"}}},
45+
{"userTag", struct{ V uint }{1}, url.Values{"V": {"1"}}},
46+
{"userTag", struct{ V float32 }{0.1}, url.Values{"V": {"0.1"}}},
47+
{"userTag", struct{ V bool }{true}, url.Values{"V": {"true"}}},
4748

4849
// bool-specific options
4950
{
51+
"url",
5052
struct {
5153
V bool `url:",int"`
5254
}{false},
5355
url.Values{"V": {"0"}},
5456
},
5557
{
58+
"url",
5659
struct {
5760
V bool `url:",int"`
5861
}{true},
@@ -61,30 +64,35 @@ func TestValues_BasicTypes(t *testing.T) {
6164

6265
// time values
6366
{
67+
"",
6468
struct {
6569
V time.Time
6670
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
6771
url.Values{"V": {"2000-01-01T12:34:56Z"}},
6872
},
6973
{
74+
"url",
7075
struct {
7176
V time.Time `url:",unix"`
7277
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
7378
url.Values{"V": {"946730096"}},
7479
},
7580
{
81+
"url",
7682
struct {
7783
V time.Time `url:",unixmilli"`
7884
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
7985
url.Values{"V": {"946730096000"}},
8086
},
8187
{
88+
"url",
8289
struct {
8390
V time.Time `url:",unixnano"`
8491
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
8592
url.Values{"V": {"946730096000000000"}},
8693
},
8794
{
95+
"url",
8896
struct {
8997
V time.Time `layout:"2006-01-02"`
9098
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
@@ -93,7 +101,7 @@ func TestValues_BasicTypes(t *testing.T) {
93101
}
94102

95103
for _, tt := range tests {
96-
testValue(t, tt.input, tt.want)
104+
testValue(t, tt.myTag, tt.input, tt.want)
97105
}
98106
}
99107

@@ -129,7 +137,7 @@ func TestValues_Pointers(t *testing.T) {
129137
}
130138

131139
for _, tt := range tests {
132-
testValue(t, tt.input, tt.want)
140+
testValue(t, "url", tt.input, tt.want)
133141
}
134142
}
135143

@@ -268,7 +276,7 @@ func TestValues_Slices(t *testing.T) {
268276
}
269277

270278
for _, tt := range tests {
271-
testValue(t, tt.input, tt.want)
279+
testValue(t, "url", tt.input, tt.want)
272280
}
273281
}
274282

@@ -325,7 +333,7 @@ func TestValues_NestedTypes(t *testing.T) {
325333
}
326334

327335
for _, tt := range tests {
328-
testValue(t, tt.input, tt.want)
336+
testValue(t, "url", tt.input, tt.want)
329337
}
330338
}
331339

@@ -365,7 +373,7 @@ func TestValues_OmitEmpty(t *testing.T) {
365373
}
366374

367375
for _, tt := range tests {
368-
testValue(t, tt.input, tt.want)
376+
testValue(t, "url", tt.input, tt.want)
369377
}
370378
}
371379

@@ -420,12 +428,12 @@ func TestValues_EmbeddedStructs(t *testing.T) {
420428
}
421429

422430
for _, tt := range tests {
423-
testValue(t, tt.input, tt.want)
431+
testValue(t, "url", tt.input, tt.want)
424432
}
425433
}
426434

427435
func TestValues_InvalidInput(t *testing.T) {
428-
_, err := Values("")
436+
_, err := Values("", "")
429437
if err == nil {
430438
t.Errorf("expected Values() to return an error on invalid input")
431439
}
@@ -480,7 +488,7 @@ func TestValues_CustomEncodingSlice(t *testing.T) {
480488
}
481489

482490
for _, tt := range tests {
483-
testValue(t, tt.input, tt.want)
491+
testValue(t, "", tt.input, tt.want)
484492
}
485493
}
486494

@@ -504,7 +512,7 @@ func TestValues_CustomEncoding_Error(t *testing.T) {
504512
},
505513
}
506514
for _, tt := range tests {
507-
_, err := Values(tt.input)
515+
_, err := Values("", tt.input)
508516
if err == nil {
509517
t.Errorf("Values(%q) did not return expected encoding error", tt.input)
510518
}
@@ -574,7 +582,7 @@ func TestValues_CustomEncodingInt(t *testing.T) {
574582
}
575583

576584
for _, tt := range tests {
577-
testValue(t, tt.input, tt.want)
585+
testValue(t, "", tt.input, tt.want)
578586
}
579587
}
580588

@@ -657,7 +665,7 @@ func TestValues_CustomEncodingPointer(t *testing.T) {
657665
}
658666

659667
for _, tt := range tests {
660-
testValue(t, tt.input, tt.want)
668+
testValue(t, "", tt.input, tt.want)
661669
}
662670
}
663671

0 commit comments

Comments
 (0)