Skip to content

Commit

Permalink
address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
ssoroka committed Mar 18, 2022
1 parent 74a8427 commit 580b8b4
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
28 changes: 21 additions & 7 deletions binding/form_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,17 @@ 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 || err != nil {
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 || err != nil {
return ok, err
}
if len(vs) != value.Len() {
return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
}
Expand All @@ -194,19 +200,27 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
if len(vs) > 0 {
val = vs[0]
}
if ok, err := trySetCustom(val, value); ok || err != nil {
return ok, err
}
return true, setWithProperType(val, value, field)
}
}

func setWithProperType(val string, value reflect.Value, field reflect.StructField) error {
if value.Kind() != reflect.Struct {
if u, ok := value.Addr().Interface().(encoding.TextUnmarshaler); ok {
return u.UnmarshalText(bytesconv.StringToBytes(val))
func trySetCustom(val string, value reflect.Value) (isSet bool, err error) {
switch v := value.Addr().Interface().(type) {
case encoding.TextUnmarshaler:
if value.Kind() != reflect.Struct {
return true, v.UnmarshalText([]byte(val))
}
case BindUnmarshaler:
return true, v.UnmarshalParam(val)
}
if u, ok := value.Addr().Interface().(BindUnmarshaler); ok {
return u.UnmarshalParam(val)
}

return false, nil
}

func setWithProperType(val string, value reflect.Value, field reflect.StructField) error {
switch value.Kind() {
case reflect.Int:
return setIntField(val, 0, value)
Expand Down
47 changes: 47 additions & 0 deletions binding/form_mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,50 @@ func TestMappingCustomStructType(t *testing.T) {
assert.EqualValues(t, "/foo", s.FileData.Path)
assert.EqualValues(t, "happiness", s.FileData.Name)
}

func TestMappingCustomPointerStructType(t *testing.T) {
var s struct {
FileData *customType `form:"data"`
}
err := mappingByPtr(&s, formSource{"data": {`file:/foo:happiness`}}, "form")
assert.NoError(t, err)

assert.EqualValues(t, "file", s.FileData.Protocol)
assert.EqualValues(t, "/foo", s.FileData.Path)
assert.EqualValues(t, "happiness", s.FileData.Name)
}

type MySlice []string

func (s *MySlice) UnmarshalParam(param string) error {
*s = MySlice(strings.Split(param, ","))
return nil
}

func TestMappingCustomSliceType(t *testing.T) {
var s struct {
Permissions MySlice `form:"permissions"`
}
err := mappingByPtr(&s, formSource{"permissions": {"read,write,delete"}}, "form")
assert.NoError(t, err)

assert.EqualValues(t, []string{"read", "write", "delete"}, s.Permissions)
}

type MyArray [3]string

func (s *MyArray) UnmarshalParam(param string) error {
parts := strings.Split(param, ",")
*s = MyArray([3]string{parts[0], parts[1], parts[2]})
return nil
}

func TestMappingCustomArrayType(t *testing.T) {
var s struct {
Permissions MyArray `form:"permissions"`
}
err := mappingByPtr(&s, formSource{"permissions": {"read,write,delete"}}, "form")
assert.NoError(t, err)

assert.EqualValues(t, [3]string{"read", "write", "delete"}, s.Permissions)
}

0 comments on commit 580b8b4

Please sign in to comment.