Skip to content

Commit 24d6764

Browse files
bruceNu1lsoaradmin
andauthored
feat(form): add custom string slice for form tag unmarshal (#3970) (#3971)
Co-authored-by: Bruce Lee <[email protected]>
1 parent e0d46de commit 24d6764

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

binding/form_mapping.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,25 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
193193
if !ok {
194194
vs = []string{opt.defaultValue}
195195
}
196+
197+
if ok, err = trySetCustom(vs[0], value); ok {
198+
return ok, err
199+
}
200+
196201
return true, setSlice(vs, value, field)
197202
case reflect.Array:
198203
if !ok {
199204
vs = []string{opt.defaultValue}
200205
}
206+
207+
if ok, err = trySetCustom(vs[0], value); ok {
208+
return ok, err
209+
}
210+
201211
if len(vs) != value.Len() {
202212
return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
203213
}
214+
204215
return true, setArray(vs, value, field)
205216
default:
206217
var val string

binding/form_mapping_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package binding
66

77
import (
8+
"encoding/hex"
89
"fmt"
910
"mime/multipart"
1011
"reflect"
@@ -422,3 +423,89 @@ func TestMappingCustomPointerStructTypeWithURITag(t *testing.T) {
422423
assert.EqualValues(t, "/foo", s.FileData.Path)
423424
assert.EqualValues(t, "happiness", s.FileData.Name)
424425
}
426+
427+
type customPath []string
428+
429+
func (p *customPath) UnmarshalParam(param string) error {
430+
elems := strings.Split(param, "/")
431+
n := len(elems)
432+
if n < 2 {
433+
return fmt.Errorf("invalid format")
434+
}
435+
436+
*p = elems
437+
return nil
438+
}
439+
440+
func TestMappingCustomSliceUri(t *testing.T) {
441+
var s struct {
442+
FileData customPath `uri:"path"`
443+
}
444+
err := mappingByPtr(&s, formSource{"path": {`bar/foo`}}, "uri")
445+
assert.NoError(t, err)
446+
447+
assert.EqualValues(t, "bar", s.FileData[0])
448+
assert.EqualValues(t, "foo", s.FileData[1])
449+
}
450+
451+
func TestMappingCustomSliceForm(t *testing.T) {
452+
var s struct {
453+
FileData customPath `form:"path"`
454+
}
455+
err := mappingByPtr(&s, formSource{"path": {`bar/foo`}}, "form")
456+
assert.NoError(t, err)
457+
458+
assert.EqualValues(t, "bar", s.FileData[0])
459+
assert.EqualValues(t, "foo", s.FileData[1])
460+
}
461+
462+
type objectID [12]byte
463+
464+
func (o *objectID) UnmarshalParam(param string) error {
465+
oid, err := convertTo(param)
466+
if err != nil {
467+
return err
468+
}
469+
470+
*o = oid
471+
return nil
472+
}
473+
474+
func convertTo(s string) (objectID, error) {
475+
var nilObjectID objectID
476+
if len(s) != 24 {
477+
return nilObjectID, fmt.Errorf("invalid format")
478+
}
479+
480+
var oid [12]byte
481+
_, err := hex.Decode(oid[:], []byte(s))
482+
if err != nil {
483+
return nilObjectID, err
484+
}
485+
486+
return oid, nil
487+
}
488+
489+
func TestMappingCustomArrayUri(t *testing.T) {
490+
var s struct {
491+
FileData objectID `uri:"id"`
492+
}
493+
val := `664a062ac74a8ad104e0e80f`
494+
err := mappingByPtr(&s, formSource{"id": {val}}, "uri")
495+
assert.NoError(t, err)
496+
497+
expected, _ := convertTo(val)
498+
assert.EqualValues(t, expected, s.FileData)
499+
}
500+
501+
func TestMappingCustomArrayForm(t *testing.T) {
502+
var s struct {
503+
FileData objectID `form:"id"`
504+
}
505+
val := `664a062ac74a8ad104e0e80f`
506+
err := mappingByPtr(&s, formSource{"id": {val}}, "form")
507+
assert.NoError(t, err)
508+
509+
expected, _ := convertTo(val)
510+
assert.EqualValues(t, expected, s.FileData)
511+
}

0 commit comments

Comments
 (0)