Skip to content

Commit fb090f6

Browse files
committed
add the support of time.Duration and time.Time for BindURLValues
1 parent 467c0cc commit fb090f6

File tree

1 file changed

+43
-4
lines changed

1 file changed

+43
-4
lines changed

binder/binder_values.go

+43-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"reflect"
2929
"strconv"
3030
"strings"
31+
"time"
3132
)
3233

3334
// BindUnmarshaler is the interface used to wrap the UnmarshalParam method.
@@ -40,6 +41,27 @@ type BindUnmarshaler interface {
4041
//
4142
// Notice: tag is the name of the struct tag. such as "form", "query", etc.
4243
// If the tag value is equal to "-", ignore this field.
44+
//
45+
// Support the types of the struct fields as follow:
46+
// - bool
47+
// - int
48+
// - int8
49+
// - int16
50+
// - int32
51+
// - int64
52+
// - uint
53+
// - uint8
54+
// - uint16
55+
// - uint32
56+
// - uint64
57+
// - string
58+
// - float32
59+
// - float64
60+
// - time.Time // use time.Time.UnmarshalText(), so only support RFC3339 format
61+
// - time.Duration // use time.ParseDuration()
62+
// - interface { UnmarshalBind(param string) error }
63+
// And any pointer to the type above.
64+
//
4365
func BindURLValues(ptr interface{}, data url.Values, tag string) error {
4466
typ := reflect.TypeOf(ptr).Elem()
4567
val := reflect.ValueOf(ptr).Elem()
@@ -135,6 +157,13 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
135157
case reflect.Int32:
136158
return setIntField(val, 32, structField)
137159
case reflect.Int64:
160+
if _, ok := structField.Interface().(time.Duration); ok {
161+
v, err := time.ParseDuration(val)
162+
if err == nil {
163+
structField.SetInt(int64(v))
164+
}
165+
return err
166+
}
138167
return setIntField(val, 64, structField)
139168
case reflect.Uint:
140169
return setUintField(val, 0, structField)
@@ -155,6 +184,12 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
155184
case reflect.String:
156185
structField.SetString(val)
157186
default:
187+
if _, ok := structField.Interface().(time.Time); ok {
188+
if val == "" {
189+
return nil
190+
}
191+
return structField.Addr().Interface().(*time.Time).UnmarshalText([]byte(val))
192+
}
158193
return errors.New("unknown type")
159194
}
160195
return nil
@@ -200,8 +235,9 @@ func unmarshalFieldPtr(value string, field reflect.Value) (bool, error) {
200235

201236
func setIntField(value string, bitSize int, field reflect.Value) error {
202237
if value == "" {
203-
value = "0"
238+
return nil
204239
}
240+
205241
intVal, err := strconv.ParseInt(value, 10, bitSize)
206242
if err == nil {
207243
field.SetInt(intVal)
@@ -211,8 +247,9 @@ func setIntField(value string, bitSize int, field reflect.Value) error {
211247

212248
func setUintField(value string, bitSize int, field reflect.Value) error {
213249
if value == "" {
214-
value = "0"
250+
return nil
215251
}
252+
216253
uintVal, err := strconv.ParseUint(value, 10, bitSize)
217254
if err == nil {
218255
field.SetUint(uintVal)
@@ -222,8 +259,9 @@ func setUintField(value string, bitSize int, field reflect.Value) error {
222259

223260
func setBoolField(value string, field reflect.Value) error {
224261
if value == "" {
225-
value = "false"
262+
return nil
226263
}
264+
227265
boolVal, err := strconv.ParseBool(value)
228266
if err == nil {
229267
field.SetBool(boolVal)
@@ -233,8 +271,9 @@ func setBoolField(value string, field reflect.Value) error {
233271

234272
func setFloatField(value string, bitSize int, field reflect.Value) error {
235273
if value == "" {
236-
value = "0.0"
274+
return nil
237275
}
276+
238277
floatVal, err := strconv.ParseFloat(value, bitSize)
239278
if err == nil {
240279
field.SetFloat(floatVal)

0 commit comments

Comments
 (0)