github.com/songzhibin97/gkit@v1.2.13/tools/bind/multlpart_form_mapping.go (about)

     1  package bind
     2  
     3  import (
     4  	"errors"
     5  	"mime/multipart"
     6  	"net/http"
     7  	"reflect"
     8  )
     9  
    10  type multipartRequest http.Request
    11  
    12  var _ setter = (*multipartRequest)(nil)
    13  
    14  // TrySet tries to set a value by the multipart request with the binding a form file
    15  func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error) {
    16  	if files := r.MultipartForm.File[key]; len(files) != 0 {
    17  		return setByMultipartFormFile(value, field, files)
    18  	}
    19  
    20  	return setByForm(value, field, r.MultipartForm.Value, key, opt)
    21  }
    22  
    23  func setByMultipartFormFile(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
    24  	// 判断value 类型
    25  	switch value.Kind() {
    26  	case reflect.Ptr:
    27  		switch value.Interface().(type) {
    28  		case *multipart.FileHeader:
    29  			value.Set(reflect.ValueOf(files[0]))
    30  			return true, nil
    31  		}
    32  	case reflect.Struct:
    33  		switch value.Interface().(type) {
    34  		case multipart.FileHeader:
    35  			value.Set(reflect.ValueOf(*files[0]))
    36  			return true, nil
    37  		}
    38  	case reflect.Slice:
    39  		slice := reflect.MakeSlice(value.Type(), len(files), len(files))
    40  		isSetted, err = setArrayOfMultipartFormFiles(slice, field, files)
    41  		if err != nil || !isSetted {
    42  			return isSetted, err
    43  		}
    44  		value.Set(slice)
    45  		return true, nil
    46  	case reflect.Array:
    47  		return setArrayOfMultipartFormFiles(value, field, files)
    48  	}
    49  	return false, errors.New("unsupported field type for multipart.FileHeader")
    50  }
    51  
    52  func setArrayOfMultipartFormFiles(value reflect.Value, field reflect.StructField, files []*multipart.FileHeader) (isSetted bool, err error) {
    53  	if value.Len() != len(files) {
    54  		return false, errors.New("unsupported len of array for []*multipart.FileHeader")
    55  	}
    56  	for i := range files {
    57  		setted, err := setByMultipartFormFile(value.Index(i), field, files[i:i+1])
    58  		if err != nil || !setted {
    59  			return setted, err
    60  		}
    61  	}
    62  	return true, nil
    63  }