@@ -30,6 +30,13 @@ type BindUnmarshaler interface {
30
30
UnmarshalParam (param string ) error
31
31
}
32
32
33
+ // bindMultipleUnmarshaler is used by binder to unmarshal multiple values from request at once to
34
+ // type implementing this interface. For example request could have multiple query fields `?a=1&a=2&b=test` in that case
35
+ // for `a` following slice `["1", "2"] will be passed to unmarshaller.
36
+ type bindMultipleUnmarshaler interface {
37
+ UnmarshalParams (params []string ) error
38
+ }
39
+
33
40
// BindPathParams binds path params to bindable object
34
41
func (b * DefaultBinder ) BindPathParams (c Context , i interface {}) error {
35
42
names := c .ParamNames ()
@@ -217,8 +224,15 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
217
224
continue
218
225
}
219
226
227
+ if ok , err := unmarshalInputsToField (typeField .Type .Kind (), inputValue , structField ); ok {
228
+ if err != nil {
229
+ return err
230
+ }
231
+ continue
232
+ }
233
+
220
234
// Call this first, in case we're dealing with an alias to an array type
221
- if ok , err := unmarshalField (typeField .Type .Kind (), inputValue [0 ], structField ); ok {
235
+ if ok , err := unmarshalInputToField (typeField .Type .Kind (), inputValue [0 ], structField ); ok {
222
236
if err != nil {
223
237
return err
224
238
}
@@ -245,7 +259,7 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
245
259
246
260
func setWithProperType (valueKind reflect.Kind , val string , structField reflect.Value ) error {
247
261
// But also call it here, in case we're dealing with an array of BindUnmarshalers
248
- if ok , err := unmarshalField (valueKind , val , structField ); ok {
262
+ if ok , err := unmarshalInputToField (valueKind , val , structField ); ok {
249
263
return err
250
264
}
251
265
@@ -286,33 +300,39 @@ func setWithProperType(valueKind reflect.Kind, val string, structField reflect.V
286
300
return nil
287
301
}
288
302
289
- func unmarshalField (valueKind reflect.Kind , val string , field reflect.Value ) (bool , error ) {
290
- switch valueKind {
291
- case reflect . Ptr :
292
- return unmarshalFieldPtr ( val , field )
293
- default :
294
- return unmarshalFieldNonPtr ( val , field )
303
+ func unmarshalInputsToField (valueKind reflect.Kind , values [] string , field reflect.Value ) (bool , error ) {
304
+ if valueKind == reflect . Ptr {
305
+ if field . IsNil () {
306
+ field . Set ( reflect . New ( field . Type (). Elem ()) )
307
+ }
308
+ field = field . Elem ( )
295
309
}
296
- }
297
310
298
- func unmarshalFieldNonPtr (value string , field reflect.Value ) (bool , error ) {
299
311
fieldIValue := field .Addr ().Interface ()
300
- if unmarshaler , ok := fieldIValue .(BindUnmarshaler ); ok {
301
- return true , unmarshaler .UnmarshalParam (value )
302
- }
303
- if unmarshaler , ok := fieldIValue .(encoding.TextUnmarshaler ); ok {
304
- return true , unmarshaler .UnmarshalText ([]byte (value ))
312
+ unmarshaler , ok := fieldIValue .(bindMultipleUnmarshaler )
313
+ if ! ok {
314
+ return false , nil
305
315
}
306
-
307
- return false , nil
316
+ return true , unmarshaler .UnmarshalParams (values )
308
317
}
309
318
310
- func unmarshalFieldPtr (value string , field reflect.Value ) (bool , error ) {
311
- if field .IsNil () {
312
- // Initialize the pointer to a nil value
313
- field .Set (reflect .New (field .Type ().Elem ()))
319
+ func unmarshalInputToField (valueKind reflect.Kind , val string , field reflect.Value ) (bool , error ) {
320
+ if valueKind == reflect .Ptr {
321
+ if field .IsNil () {
322
+ field .Set (reflect .New (field .Type ().Elem ()))
323
+ }
324
+ field = field .Elem ()
314
325
}
315
- return unmarshalFieldNonPtr (value , field .Elem ())
326
+
327
+ fieldIValue := field .Addr ().Interface ()
328
+ switch unmarshaler := fieldIValue .(type ) {
329
+ case BindUnmarshaler :
330
+ return true , unmarshaler .UnmarshalParam (val )
331
+ case encoding.TextUnmarshaler :
332
+ return true , unmarshaler .UnmarshalText ([]byte (val ))
333
+ }
334
+
335
+ return false , nil
316
336
}
317
337
318
338
func setIntField (value string , bitSize int , field reflect.Value ) error {
0 commit comments