55package binding
66
77import (
8+ "encoding"
89 "errors"
910 "fmt"
1011 "mime/multipart"
@@ -136,6 +137,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
136137type setOptions struct {
137138 isDefaultExists bool
138139 defaultValue string
140+ parser string
139141}
140142
141143func tryToSetValue (value reflect.Value , field reflect.StructField , setter setter , tag string ) (bool , error ) {
@@ -167,6 +169,8 @@ func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter
167169 setOpt .defaultValue = strings .ReplaceAll (v , ";" , "," )
168170 }
169171 }
172+ } else if k , v = head (opt , "=" ); k == "parser" {
173+ setOpt .parser = v
170174 }
171175 }
172176
@@ -190,6 +194,20 @@ func trySetCustom(val string, value reflect.Value) (isSet bool, err error) {
190194 return false , nil
191195}
192196
197+ // trySetUsingParser tries to set a custom type value based on the presence of the "parser" tag on the field.
198+ // If the parser tag does not exist or does not match any of the supported parsers, gin will skip over this.
199+ func trySetUsingParser (val string , value reflect.Value , parser string ) (isSet bool , err error ) {
200+ switch parser {
201+ case "encoding.TextUnmarshaler" :
202+ v , ok := value .Addr ().Interface ().(encoding.TextUnmarshaler )
203+ if ! ok {
204+ return false , nil
205+ }
206+ return true , v .UnmarshalText ([]byte (val ))
207+ }
208+ return false , nil
209+ }
210+
193211func trySplit (vs []string , field reflect.StructField ) (newVs []string , err error ) {
194212 cfTag := field .Tag .Get ("collection_format" )
195213 if cfTag == "" || cfTag == "multi" {
@@ -207,7 +225,7 @@ func trySplit(vs []string, field reflect.StructField) (newVs []string, err error
207225 case "pipes" :
208226 sep = "|"
209227 default :
210- return vs , fmt .Errorf ("%s is not supported in the collection_format. (csv, ssv, pipes)" , cfTag )
228+ return vs , fmt .Errorf ("%s is not supported in the collection_format. (multi, csv, ssv, tsv , pipes)" , cfTag )
211229 }
212230
213231 totalLength := 0
@@ -230,7 +248,7 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
230248
231249 switch value .Kind () {
232250 case reflect .Slice :
233- if ! ok {
251+ if ! ok || len ( vs ) == 0 || ( len ( vs ) > 0 && vs [ 0 ] == "" ) {
234252 vs = []string {opt .defaultValue }
235253
236254 // pre-process the default value for multi if present
@@ -240,17 +258,19 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
240258 }
241259 }
242260
243- if ok , err = trySetCustom (vs [0 ], value ); ok {
261+ if ok , err = trySetUsingParser (vs [0 ], value , opt .parser ); ok {
262+ return ok , err
263+ } else if ok , err = trySetCustom (vs [0 ], value ); ok {
244264 return ok , err
245265 }
246266
247267 if vs , err = trySplit (vs , field ); err != nil {
248268 return false , err
249269 }
250270
251- return true , setSlice (vs , value , field )
271+ return true , setSlice (vs , value , field , opt )
252272 case reflect .Array :
253- if ! ok {
273+ if ! ok || len ( vs ) == 0 || ( len ( vs ) > 0 && vs [ 0 ] == "" ) {
254274 vs = []string {opt .defaultValue }
255275
256276 // pre-process the default value for multi if present
@@ -260,7 +280,9 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
260280 }
261281 }
262282
263- if ok , err = trySetCustom (vs [0 ], value ); ok {
283+ if ok , err = trySetUsingParser (vs [0 ], value , opt .parser ); ok {
284+ return ok , err
285+ } else if ok , err = trySetCustom (vs [0 ], value ); ok {
264286 return ok , err
265287 }
266288
@@ -272,27 +294,32 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
272294 return false , fmt .Errorf ("%q is not valid value for %s" , vs , value .Type ().String ())
273295 }
274296
275- return true , setArray (vs , value , field )
297+ return true , setArray (vs , value , field , opt )
276298 default :
277299 var val string
278- if ! ok {
300+ if ! ok || len ( vs ) == 0 || ( len ( vs ) > 0 && vs [ 0 ] == "" ) {
279301 val = opt .defaultValue
280- }
281-
282- if len (vs ) > 0 {
302+ } else if len (vs ) > 0 {
283303 val = vs [0 ]
284- if val == "" {
285- val = opt .defaultValue
286- }
287304 }
288- if ok , err := trySetCustom (val , value ); ok {
305+
306+ if ok , err = trySetUsingParser (val , value , opt .parser ); ok {
307+ return ok , err
308+ } else if ok , err = trySetCustom (val , value ); ok {
289309 return ok , err
290310 }
291- return true , setWithProperType (val , value , field )
311+ return true , setWithProperType (val , value , field , opt )
292312 }
293313}
294314
295- func setWithProperType (val string , value reflect.Value , field reflect.StructField ) error {
315+ func setWithProperType (val string , value reflect.Value , field reflect.StructField , opt setOptions ) error {
316+ // this if-check is required for parsing nested types like []MyId, where MyId is [12]byte
317+ if ok , err := trySetUsingParser (val , value , opt .parser ); ok {
318+ return err
319+ } else if ok , err = trySetCustom (val , value ); ok {
320+ return err
321+ }
322+
296323 switch value .Kind () {
297324 case reflect .Int :
298325 return setIntField (val , 0 , value )
@@ -340,7 +367,7 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
340367 if ! value .Elem ().IsValid () {
341368 value .Set (reflect .New (value .Type ().Elem ()))
342369 }
343- return setWithProperType (val , value .Elem (), field )
370+ return setWithProperType (val , value .Elem (), field , opt )
344371 default :
345372 return errUnknownType
346373 }
@@ -447,19 +474,19 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
447474 return nil
448475}
449476
450- func setArray (vals []string , value reflect.Value , field reflect.StructField ) error {
477+ func setArray (vals []string , value reflect.Value , field reflect.StructField , opt setOptions ) error {
451478 for i , s := range vals {
452- err := setWithProperType (s , value .Index (i ), field )
479+ err := setWithProperType (s , value .Index (i ), field , opt )
453480 if err != nil {
454481 return err
455482 }
456483 }
457484 return nil
458485}
459486
460- func setSlice (vals []string , value reflect.Value , field reflect.StructField ) error {
487+ func setSlice (vals []string , value reflect.Value , field reflect.StructField , opt setOptions ) error {
461488 slice := reflect .MakeSlice (value .Type (), len (vals ), len (vals ))
462- err := setArray (vals , slice , field )
489+ err := setArray (vals , slice , field , opt )
463490 if err != nil {
464491 return err
465492 }
0 commit comments