ソースを参照

add support arrays on mapping (#1797)

* add support arrays on mapping

* not allow default value on array mapping
Dmitry Kutakov 6 年 前
コミット
483f828bce
2 ファイル変更48 行追加3 行削除
  1. 28 0
      binding/binding_test.go
  2. 20 3
      binding/form_mapping.go

+ 28 - 0
binding/binding_test.go

@@ -1430,3 +1430,31 @@ func TestBindingTimeDuration(t *testing.T) {
 	err = Form.Bind(req, &s)
 	assert.Error(t, err)
 }
+
+func TestBindingArray(t *testing.T) {
+	var s struct {
+		Nums [2]int `form:"nums,default=4"`
+	}
+
+	// default
+	req := formPostRequest("", "")
+	err := Form.Bind(req, &s)
+	assert.Error(t, err)
+	assert.Equal(t, [2]int{0, 0}, s.Nums)
+
+	// ok
+	req = formPostRequest("", "nums=3&nums=8")
+	err = Form.Bind(req, &s)
+	assert.NoError(t, err)
+	assert.Equal(t, [2]int{3, 8}, s.Nums)
+
+	// not enough vals
+	req = formPostRequest("", "nums=3")
+	err = Form.Bind(req, &s)
+	assert.Error(t, err)
+
+	// error
+	req = formPostRequest("", "nums=3&nums=wrong")
+	err = Form.Bind(req, &s)
+	assert.Error(t, err)
+}

+ 20 - 3
binding/form_mapping.go

@@ -6,6 +6,7 @@ package binding
 
 import (
 	"errors"
+	"fmt"
 	"reflect"
 	"strconv"
 	"strings"
@@ -118,6 +119,14 @@ func tryToSetValue(value reflect.Value, field reflect.StructField, form map[stri
 			vs = []string{defaultValue}
 		}
 		return true, setSlice(vs, value, field)
+	case reflect.Array:
+		if !ok {
+			vs = []string{defaultValue}
+		}
+		if len(vs) != value.Len() {
+			return false, fmt.Errorf("%q is not valid value for %s", vs, value.Type().String())
+		}
+		return true, setArray(vs, value, field)
 	default:
 		var val string
 		if !ok {
@@ -256,14 +265,22 @@ func setTimeField(val string, structField reflect.StructField, value reflect.Val
 	return nil
 }
 
-func setSlice(vals []string, value reflect.Value, field reflect.StructField) error {
-	slice := reflect.MakeSlice(value.Type(), len(vals), len(vals))
+func setArray(vals []string, value reflect.Value, field reflect.StructField) error {
 	for i, s := range vals {
-		err := setWithProperType(s, slice.Index(i), field)
+		err := setWithProperType(s, value.Index(i), field)
 		if err != nil {
 			return err
 		}
 	}
+	return nil
+}
+
+func setSlice(vals []string, value reflect.Value, field reflect.StructField) error {
+	slice := reflect.MakeSlice(value.Type(), len(vals), len(vals))
+	err := setArray(vals, slice, field)
+	if err != nil {
+		return err
+	}
 	value.Set(slice)
 	return nil
 }