diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 1244b522..e76e7510 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -300,6 +300,11 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][ } func setWithProperType(val string, value reflect.Value, field reflect.StructField) error { + // If it is a string type, no spaces are removed, and the user data is not modified here + if value.Kind() != reflect.String { + val = strings.TrimSpace(val) + } + switch value.Kind() { case reflect.Int: return setIntField(val, 0, value) @@ -404,6 +409,11 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val timeFormat = time.RFC3339 } + if val == "" { + value.Set(reflect.ValueOf(time.Time{})) + return nil + } + switch tf := strings.ToLower(timeFormat); tf { case "unix", "unixmilli", "unixmicro", "unixnano": tv, err := strconv.ParseInt(val, 10, 64) @@ -427,11 +437,6 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val return nil } - if val == "" { - value.Set(reflect.ValueOf(time.Time{})) - return nil - } - l := time.Local if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC { l = time.UTC @@ -475,6 +480,10 @@ func setSlice(vals []string, value reflect.Value, field reflect.StructField) err } func setTimeDuration(val string, value reflect.Value) error { + if val == "" { + val = "0" + } + d, err := time.ParseDuration(val) if err != nil { return err diff --git a/binding/form_mapping_test.go b/binding/form_mapping_test.go index 006eddf1..e007573c 100644 --- a/binding/form_mapping_test.go +++ b/binding/form_mapping_test.go @@ -226,7 +226,35 @@ func TestMappingTime(t *testing.T) { require.Error(t, err) } +type bindTestData struct { + need any + got any + in map[string][]string +} + +func TestMappingTimeUnixNano(t *testing.T) { + type needFixUnixNanoEmpty struct { + CreateTime time.Time `form:"createTime" time_format:"unixNano"` + } + + // ok + tests := []bindTestData{ + {need: &needFixUnixNanoEmpty{}, got: &needFixUnixNanoEmpty{}, in: formSource{"createTime": []string{" "}}}, + {need: &needFixUnixNanoEmpty{}, got: &needFixUnixNanoEmpty{}, in: formSource{"createTime": []string{}}}, + } + + for _, v := range tests { + err := mapForm(v.got, v.in) + require.NoError(t, err) + assert.Equal(t, v.need, v.got) + } +} + func TestMappingTimeDuration(t *testing.T) { + type needFixDurationEmpty struct { + Duration time.Duration `form:"duration"` + } + var s struct { D time.Duration } @@ -236,6 +264,17 @@ func TestMappingTimeDuration(t *testing.T) { require.NoError(t, err) assert.Equal(t, 5*time.Second, s.D) + // ok + tests := []bindTestData{ + {need: &needFixDurationEmpty{}, got: &needFixDurationEmpty{}, in: formSource{"duration": []string{" "}}}, + {need: &needFixDurationEmpty{}, got: &needFixDurationEmpty{}, in: formSource{"duration": []string{}}}, + } + + for _, v := range tests { + err := mapForm(v.got, v.in) + require.NoError(t, err) + assert.Equal(t, v.need, v.got) + } // error err = mappingByPtr(&s, formSource{"D": {"wrong"}}, "form") require.Error(t, err)