Repository: gin-gonic/gin
Pull request #1797 (2019-03-05 17:26:02)

add support arrays on mapping
```
var s struct {
	Nums [2]int `form:"nums"`
}
req := formPostRequest("", "nums=3&nums=8")
Form.Bind(req, &s)
```

codecov[bot]: # [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=h1) Report
> Merging [#1797](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=desc) into [master](https://codecov.io/gh/gin-gonic/gin/commit/057f63b1bb1cca059173363d10c3de9512ee1110?src=pr&el=desc) will **decrease** coverage by `0.08%`.
> The diff coverage is `83.33%`.

[![Impacted file tree graph](https://codecov.io/gh/gin-gonic/gin/pull/1797/graphs/tree.svg?width=650&token=Qpqxhwery8&height=150&src=pr)](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1797      +/-   ##
==========================================
- Coverage   98.62%   98.53%   -0.09%     
==========================================
  Files          41       41              
  Lines        2112     2121       +9     
==========================================
+ Hits         2083     2090       +7     
- Misses         18       19       +1     
- Partials       11       12       +1
```


| [Impacted Files](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [binding/form\_mapping.go](https://codecov.io/gh/gin-gonic/gin/pull/1797/diff?src=pr&el=tree#diff-YmluZGluZy9mb3JtX21hcHBpbmcuZ28=) | `98.95% <83.33%> (-1.05%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=footer). Last update [057f63b...6639fd9](https://codecov.io/gh/gin-gonic/gin/pull/1797?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/binding/form_mapping.go b/binding/form_mapping.go
index 87edfbb..ba9d2c4 100644
--- a/binding/form_mapping.go
+++ b/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
 }


Test patch:
diff --git a/binding/binding_test.go b/binding/binding_test.go
index 5ae8795..b265af3 100644
--- a/binding/binding_test.go
+++ b/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)
+}