فهرست منبع

Support time.Time on form binding (#801)

Andrey Nering 8 سال پیش
والد
کامیت
863248034b
2فایلهای تغییر یافته به همراه42 افزوده شده و 5 حذف شده
  1. 27 0
      binding/form_mapping.go
  2. 15 5
      context_test.go

+ 27 - 0
binding/form_mapping.go

@@ -8,6 +8,7 @@ import (
 	"errors"
 	"reflect"
 	"strconv"
+	"time"
 )
 
 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)
 		} 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 {
 				return err
 			}
@@ -140,6 +147,26 @@ func setFloatField(val string, bitSize int, field reflect.Value) error {
 	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:
 // https://github.com/codegangsta/martini-contrib/issues/40
 // https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659

+ 15 - 5
context_test.go

@@ -42,6 +42,8 @@ func createMultipartRequest() *http.Request {
 	must(mw.WriteField("array", "first"))
 	must(mw.WriteField("array", "second"))
 	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)
 	must(err)
 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary)
@@ -309,11 +311,14 @@ func TestContextPostFormMultipart(t *testing.T) {
 	c.Request = createMultipartRequest()
 
 	var obj struct {
-		Foo      string   `form:"foo"`
-		Bar      string   `form:"bar"`
-		BarAsInt int      `form:"bar"`
-		Array    []string `form:"array"`
-		ID       string   `form:"id"`
+		Foo       string    `form:"foo"`
+		Bar       string    `form:"bar"`
+		BarAsInt  int       `form:"bar"`
+		Array     []string  `form:"array"`
+		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.Equal(t, obj.Foo, "bar")
@@ -321,6 +326,11 @@ func TestContextPostFormMultipart(t *testing.T) {
 	assert.Equal(t, obj.BarAsInt, 10)
 	assert.Equal(t, obj.Array, []string{"first", "second"})
 	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")
 	assert.False(t, ok)