1 Star 1 Fork 2

kristas / booting-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
value_getter.go 4.08 KB
一键复制 编辑 原始数据 按行查看 历史
kristas 提交于 2021-11-03 12:47 . feat: fix reflectx
package controller
import (
"errors"
"fmt"
"gitee.com/kristas/booting-go/framework/common/util/convert"
"gitee.com/kristas/booting-go/framework/common/util/reflectx"
"gitee.com/kristas/booting-go/framework/web"
"io"
"reflect"
)
var valueMap = map[reflect.Kind]func(param web.Param, mapper ParamMapper) (interface{}, error){
reflect.Map: buildMap,
reflect.Slice: buildSlice,
reflect.String: buildString,
reflect.Struct: buildStruct,
reflect.Ptr: buildPtr,
reflect.Interface: buildInterface,
}
func getValue(param web.Param, mapper ParamMapper) (interface{}, error) {
if handler, ok := valueMap[param.GetType().Kind()]; ok {
return handler(param, mapper)
}
return buildBaseType(param, mapper)
}
func buildBaseType(param web.Param, mapper ParamMapper) (interface{}, error) {
src, err := buildString(param, mapper)
if err != nil {
return nil, err
}
return convert.Convert(src.(string), param.GetType())
}
func buildMap(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Form:
return mapper.GetMapFromForm()
default:
return notSupportError(param)
}
}
func buildSlice(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Stream:
req := mapper.GetRequest()
bodyReader := req.Body
buf, _ := io.ReadAll(bodyReader)
return buf, nil
case web.Multipart:
return mapper.GetDataFromMultipart(param.GetName())
default:
return notSupportError(param)
}
}
func buildString(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Path:
return mapper.GetStringFromPath(param.GetName())
case web.Query:
return mapper.GetStringFromQuery(param.GetName())
case web.Header:
return mapper.GetStringFromHeader(param.GetName())
case web.Form:
return mapper.GetStringFromForm(param.GetName())
case web.Multipart:
bytes, err := mapper.GetDataFromMultipart(param.GetName())
return string(bytes), err
default:
return notSupportError(param)
}
}
func buildStruct(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Query:
return buildStructWithGetter(param, mapper.GetStringFromQuery)
case web.Body:
return mapper.BindData(param)
case web.Header:
return buildStructWithGetter(param, mapper.GetStringFromHeader)
case web.Path:
return buildStructWithGetter(param, mapper.GetStringFromPath)
default:
return notSupportError(param)
}
}
func buildPtr(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Multipart:
return mapper.GetMultipartHeader(param.GetName())
case web.Request:
return mapper.GetRequest(), nil
case web.Query:
return buildStructWithGetter(param, mapper.GetStringFromQuery)
case web.Body:
return mapper.BindData(param)
case web.Header:
return buildStructWithGetter(param, mapper.GetStringFromHeader)
case web.Path:
return buildStructWithGetter(param, mapper.GetStringFromPath)
default:
return notSupportError(param)
}
}
func buildInterface(param web.Param, mapper ParamMapper) (interface{}, error) {
switch param.GetSource() {
case web.Multipart:
return mapper.GetMultipartFile(param.GetName())
case web.Response:
return mapper.GetResponseWriter(), nil
case web.Context:
return mapper.GetContext(), nil
default:
return notSupportError(param)
}
}
type getter func(name string) (string, error)
func buildStructWithGetter(param web.Param, getter getter) (interface{}, error) {
v := reflect.New(param.GetType()).Elem()
err := reflectx.ForEachFieldV2(v.Type(), v, true,
func(field reflect.StructField, value reflect.Value) error {
tag := field.Tag.Get("json")
if tag == "" {
tag = field.Name
}
src, err := getter(tag)
if err != nil {
return err
}
err = convert.SetValue(src, field.Type, value)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return v.Interface(), nil
}
func notSupportError(param web.Param) (interface{}, error) {
return nil, errors.New(fmt.Sprintf("param %s in source %s not support", param.GetName(), param.GetSource()))
}
Go
1
https://gitee.com/kristas/booting-go.git
git@gitee.com:kristas/booting-go.git
kristas
booting-go
booting-go
v1.4.4

搜索帮助