diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 6982fd4f3b..024b809317 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -250,19 +250,24 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][ switch value.Kind() { case reflect.Slice: - if len(vs) == 0 { + if vs == nil { if !opt.isDefaultExists { return false, nil } - vs = []string{opt.defaultValue} // pre-process the default value for multi if present cfTag := field.Tag.Get("collection_format") if cfTag == "" || cfTag == "multi" { vs = strings.Split(opt.defaultValue, ",") + } else { + vs = []string{opt.defaultValue} } } + if len(vs) == 0 { + return true, setSlice(vs, value, field, opt) + } + if ok, err = trySetUsingParser(vs[0], value, opt.parser); ok { return ok, err } else if ok, err = trySetCustom(vs[0], value); ok { @@ -280,11 +285,12 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][ return false, nil } - vs = []string{opt.defaultValue} // pre-process the default value for multi if present cfTag := field.Tag.Get("collection_format") if cfTag == "" || cfTag == "multi" { vs = strings.Split(opt.defaultValue, ",") + } else { + vs = []string{opt.defaultValue} } } diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index c78f739858..ad9dd9334e 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -915,7 +915,7 @@ func TestMappingCustomSliceOfSliceUnmarshalTextDefault(t *testing.T) { var s struct { FileData []customPathUnmarshalText `form:"path,default=bar/foo;bar/foo/spam,parser=encoding.TextUnmarshaler" collection_format:"csv"` } - err := mappingByPtr(&s, formSource{"path": {}}, "form") + err := mappingByPtr(&s, formSource{"path": nil}, "form") require.NoError(t, err) assert.Equal(t, []customPathUnmarshalText{{"bar", "foo"}, {"bar", "foo", "spam"}}, s.FileData) } @@ -994,7 +994,7 @@ func TestMappingCustomArrayOfArrayUnmarshalTextDefault(t *testing.T) { var s struct { FileData []objectIDUnmarshalText `form:"ids,default=664a062ac74a8ad104e0e80e;664a062ac74a8ad104e0e80f,parser=encoding.TextUnmarshaler" collection_format:"csv"` } - err := mappingByPtr(&s, formSource{"ids": {}}, "form") + err := mappingByPtr(&s, formSource{"ids": nil}, "form") require.NoError(t, err) assert.Equal(t, []objectIDUnmarshalText{id1, id2}, s.FileData) } @@ -1079,7 +1079,7 @@ func TestMappingEmptyValues(t *testing.T) { // field present but empty err = mappingByPtr(&s, formSource{"slice": {}}, "form") require.NoError(t, err) - assert.Equal(t, []int{5}, s.Slice) + assert.Equal(t, []int{}, s.Slice) // field present with values err = mappingByPtr(&s, formSource{"slice": {"1", "2", "3"}}, "form") @@ -1108,10 +1108,15 @@ func TestMappingEmptyValues(t *testing.T) { Slice []int `form:"slice"` } - // field present but empty - err := mappingByPtr(&s, formSource{"slice": {}}, "form") + // field not present + err := mappingByPtr(&s, formSource{}, "form") require.NoError(t, err) assert.Equal(t, []int(nil), s.Slice) + + // field present but empty + err = mappingByPtr(&s, formSource{"slice": {}}, "form") + require.NoError(t, err) + assert.Equal(t, []int{}, s.Slice) }) t.Run("array without default", func(t *testing.T) { @@ -1140,7 +1145,7 @@ func TestMappingEmptyValues(t *testing.T) { // field present but empty err = mappingByPtr(&s, formSource{"slice_multi": {}, "slice_csv": {}}, "form") require.NoError(t, err) - assert.Equal(t, []int{1, 2, 3}, s.SliceMulti) - assert.Equal(t, []int{1, 2, 3}, s.SliceCsv) + assert.Equal(t, []int{}, s.SliceMulti) + assert.Equal(t, []int{}, s.SliceCsv) }) }