Skip to content

Commit

Permalink
feat(form): add custom string slice for form tag unmarshal (#3970) (#…
Browse files Browse the repository at this point in the history
…3971)

Co-authored-by: Bruce Lee <[email protected]>
  • Loading branch information
bruceNu1l and soaradmin authored May 23, 2024
1 parent e0d46de commit 24d6764
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
11 changes: 11 additions & 0 deletions binding/form_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,25 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
if !ok {
vs = []string{opt.defaultValue}
}

if ok, err = trySetCustom(vs[0], value); ok {
return ok, err
}

return true, setSlice(vs, value, field)
case reflect.Array:
if !ok {
vs = []string{opt.defaultValue}
}

if ok, err = trySetCustom(vs[0], value); ok {
return ok, err
}

if len(vs) != value.Len() {
return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
}

return true, setArray(vs, value, field)
default:
var val string
Expand Down
87 changes: 87 additions & 0 deletions binding/form_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package binding

import (
"encoding/hex"
"fmt"
"mime/multipart"
"reflect"
Expand Down Expand Up @@ -422,3 +423,89 @@ func TestMappingCustomPointerStructTypeWithURITag(t *testing.T) {
assert.EqualValues(t, "/foo", s.FileData.Path)
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)
}

0 comments on commit 24d6764

Please sign in to comment.