feat(form): add custom string slice for form tag unmarshal (#3970) (#3971)

Co-authored-by: Bruce Lee <admin@ifocusad.com>
This commit is contained in:
bruceNu1l 2024-05-23 10:16:11 +08:00 committed by GitHub
parent e0d46ded6c
commit 24d67647cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 98 additions and 0 deletions

View File

@ -193,14 +193,25 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
if !ok { if !ok {
vs = []string{opt.defaultValue} vs = []string{opt.defaultValue}
} }
if ok, err = trySetCustom(vs[0], value); ok {
return ok, err
}
return true, setSlice(vs, value, field) return true, setSlice(vs, value, field)
case reflect.Array: case reflect.Array:
if !ok { if !ok {
vs = []string{opt.defaultValue} vs = []string{opt.defaultValue}
} }
if ok, err = trySetCustom(vs[0], value); ok {
return ok, err
}
if len(vs) != value.Len() { if len(vs) != value.Len() {
return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String()) return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
} }
return true, setArray(vs, value, field) return true, setArray(vs, value, field)
default: default:
var val string var val string

View File

@ -5,6 +5,7 @@
package binding package binding
import ( import (
"encoding/hex"
"fmt" "fmt"
"mime/multipart" "mime/multipart"
"reflect" "reflect"
@ -422,3 +423,89 @@ func TestMappingCustomPointerStructTypeWithURITag(t *testing.T) {
assert.EqualValues(t, "/foo", s.FileData.Path) assert.EqualValues(t, "/foo", s.FileData.Path)
assert.EqualValues(t, "happiness", s.FileData.Name) assert.EqualValues(t, "happiness", s.FileData.Name)
} }
type customPath []string
func (p *customPath) UnmarshalParam(param string) error {
elems := strings.Split(param, "/")
n := len(elems)
if n < 2 {
return fmt.Errorf("invalid format")
}
*p = elems
return nil
}
func TestMappingCustomSliceUri(t *testing.T) {
var s struct {
FileData customPath `uri:"path"`
}
err := mappingByPtr(&s, formSource{"path": {`bar/foo`}}, "uri")
assert.NoError(t, err)
assert.EqualValues(t, "bar", s.FileData[0])
assert.EqualValues(t, "foo", s.FileData[1])
}
func TestMappingCustomSliceForm(t *testing.T) {
var s struct {
FileData customPath `form:"path"`
}
err := mappingByPtr(&s, formSource{"path": {`bar/foo`}}, "form")
assert.NoError(t, err)
assert.EqualValues(t, "bar", s.FileData[0])
assert.EqualValues(t, "foo", s.FileData[1])
}
type objectID [12]byte
func (o *objectID) UnmarshalParam(param string) error {
oid, err := convertTo(param)
if err != nil {
return err
}
*o = oid
return nil
}
func convertTo(s string) (objectID, error) {
var nilObjectID objectID
if len(s) != 24 {
return nilObjectID, fmt.Errorf("invalid format")
}
var oid [12]byte
_, err := hex.Decode(oid[:], []byte(s))
if err != nil {
return nilObjectID, err
}
return oid, nil
}
func TestMappingCustomArrayUri(t *testing.T) {
var s struct {
FileData objectID `uri:"id"`
}
val := `664a062ac74a8ad104e0e80f`
err := mappingByPtr(&s, formSource{"id": {val}}, "uri")
assert.NoError(t, err)
expected, _ := convertTo(val)
assert.EqualValues(t, expected, s.FileData)
}
func TestMappingCustomArrayForm(t *testing.T) {
var s struct {
FileData objectID `form:"id"`
}
val := `664a062ac74a8ad104e0e80f`
err := mappingByPtr(&s, formSource{"id": {val}}, "form")
assert.NoError(t, err)
expected, _ := convertTo(val)
assert.EqualValues(t, expected, s.FileData)
}