Support time.Time on form binding (#801)
This commit is contained in:
		| @ -8,6 +8,7 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strconv" | 	"strconv" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func mapForm(ptr interface{}, form map[string][]string) error { | func mapForm(ptr interface{}, form map[string][]string) error { | ||||||
| @ -52,6 +53,12 @@ func mapForm(ptr interface{}, form map[string][]string) error { | |||||||
| 			} | 			} | ||||||
| 			val.Field(i).Set(slice) | 			val.Field(i).Set(slice) | ||||||
| 		} else { | 		} else { | ||||||
|  | 			if _, isTime := structField.Interface().(time.Time); isTime { | ||||||
|  | 				if err := setTimeField(inputValue[0], typeField, structField); err != nil { | ||||||
|  | 					return err | ||||||
|  | 				} | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
| 			if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { | 			if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| @ -140,6 +147,26 @@ func setFloatField(val string, bitSize int, field reflect.Value) error { | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func setTimeField(val string, structField reflect.StructField, value reflect.Value) error { | ||||||
|  | 	timeFormat := structField.Tag.Get("time_format") | ||||||
|  | 	if timeFormat == "" { | ||||||
|  | 		return errors.New("Blank time format") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	l := time.Local | ||||||
|  | 	if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC { | ||||||
|  | 		l = time.UTC | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t, err := time.ParseInLocation(timeFormat, val, l) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	value.Set(reflect.ValueOf(t)) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // Don't pass in pointers to bind to. Can lead to bugs. See: | // Don't pass in pointers to bind to. Can lead to bugs. See: | ||||||
| // https://github.com/codegangsta/martini-contrib/issues/40 | // https://github.com/codegangsta/martini-contrib/issues/40 | ||||||
| // https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659 | // https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659 | ||||||
|  | |||||||
| @ -42,6 +42,8 @@ func createMultipartRequest() *http.Request { | |||||||
| 	must(mw.WriteField("array", "first")) | 	must(mw.WriteField("array", "first")) | ||||||
| 	must(mw.WriteField("array", "second")) | 	must(mw.WriteField("array", "second")) | ||||||
| 	must(mw.WriteField("id", "")) | 	must(mw.WriteField("id", "")) | ||||||
|  | 	must(mw.WriteField("time_local", "31/12/2016 14:55")) | ||||||
|  | 	must(mw.WriteField("time_utc", "31/12/2016 14:55")) | ||||||
| 	req, err := http.NewRequest("POST", "/", body) | 	req, err := http.NewRequest("POST", "/", body) | ||||||
| 	must(err) | 	must(err) | ||||||
| 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary) | 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary) | ||||||
| @ -314,6 +316,9 @@ func TestContextPostFormMultipart(t *testing.T) { | |||||||
| 		BarAsInt  int       `form:"bar"` | 		BarAsInt  int       `form:"bar"` | ||||||
| 		Array     []string  `form:"array"` | 		Array     []string  `form:"array"` | ||||||
| 		ID        string    `form:"id"` | 		ID        string    `form:"id"` | ||||||
|  | 		TimeLocal time.Time `form:"time_local" time_format:"02/01/2006 15:04"` | ||||||
|  | 		TimeUTC   time.Time `form:"time_utc" time_format:"02/01/2006 15:04" time_utc:"1"` | ||||||
|  | 		BlankTime time.Time `form:"blank_time" time_format:"02/01/2006 15:04"` | ||||||
| 	} | 	} | ||||||
| 	assert.NoError(t, c.Bind(&obj)) | 	assert.NoError(t, c.Bind(&obj)) | ||||||
| 	assert.Equal(t, obj.Foo, "bar") | 	assert.Equal(t, obj.Foo, "bar") | ||||||
| @ -321,6 +326,11 @@ func TestContextPostFormMultipart(t *testing.T) { | |||||||
| 	assert.Equal(t, obj.BarAsInt, 10) | 	assert.Equal(t, obj.BarAsInt, 10) | ||||||
| 	assert.Equal(t, obj.Array, []string{"first", "second"}) | 	assert.Equal(t, obj.Array, []string{"first", "second"}) | ||||||
| 	assert.Equal(t, obj.ID, "") | 	assert.Equal(t, obj.ID, "") | ||||||
|  | 	assert.Equal(t, obj.TimeLocal.Format("02/01/2006 15:04"), "31/12/2016 14:55") | ||||||
|  | 	assert.Equal(t, obj.TimeLocal.Location(), time.Local) | ||||||
|  | 	assert.Equal(t, obj.TimeUTC.Format("02/01/2006 15:04"), "31/12/2016 14:55") | ||||||
|  | 	assert.Equal(t, obj.TimeUTC.Location(), time.UTC) | ||||||
|  | 	assert.True(t, obj.BlankTime.IsZero()) | ||||||
|  |  | ||||||
| 	value, ok := c.GetQuery("foo") | 	value, ok := c.GetQuery("foo") | ||||||
| 	assert.False(t, ok) | 	assert.False(t, ok) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user