mirror of https://github.com/gin-gonic/gin.git
Merge branch 'gin-gonic:master' into master
This commit is contained in:
commit
7d8be0557f
|
@ -61,7 +61,7 @@ func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
|
||||||
|
|
||||||
// setter tries to set value on a walking by fields of a struct
|
// setter tries to set value on a walking by fields of a struct
|
||||||
type setter interface {
|
type setter interface {
|
||||||
TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error)
|
TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSet bool, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type formSource map[string][]string
|
type formSource map[string][]string
|
||||||
|
@ -69,7 +69,7 @@ type formSource map[string][]string
|
||||||
var _ setter = formSource(nil)
|
var _ setter = formSource(nil)
|
||||||
|
|
||||||
// TrySet tries to set a value by request's form source (like map[string][]string)
|
// TrySet tries to set a value by request's form source (like map[string][]string)
|
||||||
func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) {
|
func (form formSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSet bool, err error) {
|
||||||
return setByForm(value, field, form, tagValue, opt)
|
return setByForm(value, field, form, tagValue, opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,14 +92,14 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
|
||||||
isNew = true
|
isNew = true
|
||||||
vPtr = reflect.New(value.Type().Elem())
|
vPtr = reflect.New(value.Type().Elem())
|
||||||
}
|
}
|
||||||
isSetted, err := mapping(vPtr.Elem(), field, setter, tag)
|
isSet, err := mapping(vPtr.Elem(), field, setter, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if isNew && isSetted {
|
if isNew && isSet {
|
||||||
value.Set(vPtr)
|
value.Set(vPtr)
|
||||||
}
|
}
|
||||||
return isSetted, nil
|
return isSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if vKind != reflect.Struct || !field.Anonymous {
|
if vKind != reflect.Struct || !field.Anonymous {
|
||||||
|
@ -115,7 +115,7 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
|
||||||
if vKind == reflect.Struct {
|
if vKind == reflect.Struct {
|
||||||
tValue := value.Type()
|
tValue := value.Type()
|
||||||
|
|
||||||
var isSetted bool
|
var isSet bool
|
||||||
for i := 0; i < value.NumField(); i++ {
|
for i := 0; i < value.NumField(); i++ {
|
||||||
sf := tValue.Field(i)
|
sf := tValue.Field(i)
|
||||||
if sf.PkgPath != "" && !sf.Anonymous { // unexported
|
if sf.PkgPath != "" && !sf.Anonymous { // unexported
|
||||||
|
@ -125,9 +125,9 @@ func mapping(value reflect.Value, field reflect.StructField, setter setter, tag
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
isSetted = isSetted || ok
|
isSet = isSet || ok
|
||||||
}
|
}
|
||||||
return isSetted, nil
|
return isSet, nil
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ func tryToSetValue(value reflect.Value, field reflect.StructField, setter setter
|
||||||
return setter.TrySet(value, field, tagValue, setOpt)
|
return setter.TrySet(value, field, tagValue, setOpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSetted bool, err error) {
|
func setByForm(value reflect.Value, field reflect.StructField, form map[string][]string, tagValue string, opt setOptions) (isSet bool, err error) {
|
||||||
vs, ok := form[tagValue]
|
vs, ok := form[tagValue]
|
||||||
if !ok && !opt.isDefaultExists {
|
if !ok && !opt.isDefaultExists {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField
|
||||||
return setByForm(value, field, r.MultipartForm.Value, key, opt)
|
return setByForm(value, field, r.MultipartForm.Value, key, opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
|
func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) {
|
||||||
switch value.Kind() {
|
switch value.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
switch value.Interface().(type) {
|
switch value.Interface().(type) {
|
||||||
|
@ -48,9 +48,9 @@ func setByMultipartFormFile(value reflect.Value, field reflect.StructField, file
|
||||||
}
|
}
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
slice := reflect.MakeSlice(value.Type(), len(files), len(files))
|
slice := reflect.MakeSlice(value.Type(), len(files), len(files))
|
||||||
isSetted, err = setArrayOfMultipartFormFiles(slice, field, files)
|
isSet, err = setArrayOfMultipartFormFiles(slice, field, files)
|
||||||
if err != nil || !isSetted {
|
if err != nil || !isSet {
|
||||||
return isSetted, err
|
return isSet, err
|
||||||
}
|
}
|
||||||
value.Set(slice)
|
value.Set(slice)
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -60,14 +60,14 @@ func setByMultipartFormFile(value reflect.Value, field reflect.StructField, file
|
||||||
return false, ErrMultiFileHeader
|
return false, ErrMultiFileHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
|
func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSet bool, err error) {
|
||||||
if value.Len() != len(files) {
|
if value.Len() != len(files) {
|
||||||
return false, ErrMultiFileHeaderLenInvalid
|
return false, ErrMultiFileHeaderLenInvalid
|
||||||
}
|
}
|
||||||
for i := range files {
|
for i := range files {
|
||||||
setted, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
|
set, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
|
||||||
if err != nil || !setted {
|
if err != nil || !set {
|
||||||
return setted, err
|
return set, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -113,7 +113,7 @@ func (e TestErr) Error() string { return string(e) }
|
||||||
// TestErrorUnwrap tests the behavior of gin.Error with "errors.Is()" and "errors.As()".
|
// TestErrorUnwrap tests the behavior of gin.Error with "errors.Is()" and "errors.As()".
|
||||||
// "errors.Is()" and "errors.As()" have been added to the standard library in go 1.13.
|
// "errors.Is()" and "errors.As()" have been added to the standard library in go 1.13.
|
||||||
func TestErrorUnwrap(t *testing.T) {
|
func TestErrorUnwrap(t *testing.T) {
|
||||||
innerErr := TestErr("somme error")
|
innerErr := TestErr("some error")
|
||||||
|
|
||||||
// 2 layers of wrapping : use 'fmt.Errorf("%w")' to wrap a gin.Error{}, which itself wraps innerErr
|
// 2 layers of wrapping : use 'fmt.Errorf("%w")' to wrap a gin.Error{}, which itself wraps innerErr
|
||||||
err := fmt.Errorf("wrapped: %w", &Error{
|
err := fmt.Errorf("wrapped: %w", &Error{
|
||||||
|
|
Loading…
Reference in New Issue