完成基础版本基于运行时的动态结构体生成 + 参数验证

This commit is contained in:
2025-03-19 15:53:57 +08:00
parent 6b5bfaf666
commit db7779e488
5 changed files with 111 additions and 24 deletions

View File

@ -12,15 +12,22 @@ import (
"errors"
"fmt"
"git.zhangdeman.cn/zhangdeman/consts"
dynamicStructGenerate "git.zhangdeman.cn/zhangdeman/dynamic-struct"
"git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack"
"git.zhangdeman.cn/zhangdeman/serialize"
"git.zhangdeman.cn/zhangdeman/wrapper"
"github.com/go-playground/validator/v10"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"strings"
)
var validatorInstance = validator.New()
var validatorInstance *validator.Validate
func init() {
validatorInstance = validator.New()
validatorInstance.SetTagName(TagValidate)
}
// Run 执行参数验证
//
@ -31,7 +38,7 @@ func Run(sourceData []byte, fieldList []StructField) ([]byte, error) {
handleInstance := &handle{
sourceData: sourceData,
fieldList: fieldList,
dynamicStruct: wrapper.NewDynamic(),
dynamicStruct: dynamicStructGenerate.NewStruct(),
}
return handleInstance.Run()
}
@ -39,7 +46,8 @@ func Run(sourceData []byte, fieldList []StructField) ([]byte, error) {
type handle struct {
sourceData []byte
fieldList []StructField
dynamicStruct *wrapper.DynamicStruct
dynamicStruct dynamicStructGenerate.Builder
formatVal string
}
// Run 执行验证
@ -67,16 +75,20 @@ func (h *handle) Run() ([]byte, error) {
// 没出现异常, 但是value为nil, 视作参数不存在处理
continue
}
// fieldName := wrapper.String(field.JsonTag).SnakeCaseToCamel()
h.dynamicStruct.AddAny(field.JsonTag, h.generateTag(field), "dynamic_struct", sourceValue)
fieldName := wrapper.String(field.JsonTag).SnakeCaseToCamel()
fieldTag := h.generateTag(field)
h.dynamicStruct.AddField(fieldName, "", sourceValue, fieldTag, false)
}
val := h.dynamicStruct.ToStructDefaultValue()
if err := serialize.JSON.Transition(h.dynamicStruct.MapData(), &val); nil != err {
val := h.dynamicStruct.Build().New()
if err := serialize.JSON.UnmarshalWithNumber([]byte(h.formatVal), &val); nil != err {
return nil, err
}
if err := validatorInstance.Struct(val); nil != err {
return nil, GetValidateErr(val, err)
}
targetByte, _ := json.Marshal(val)
err := validatorInstance.Struct(val)
return targetByte, err
return targetByte, nil
}
// checkRequired 格式化必传参数
@ -123,46 +135,57 @@ func (h *handle) getSourceDataValue(field StructField) (any, error) {
return nil, nil
}
}
var (
val any
err error
)
defer func() {
if nil == err && nil != val {
// 更新到格式化之后的数据结构中
h.formatVal, err = sjson.Set(h.formatVal, field.TargetPath, val)
}
}()
switch field.Type {
case consts.DataTypeInt: // Int类型
fallthrough
case consts.DataTypeIntPtr: // Uint类型
val, err := gjson_hack.Int(sourceValue)
val, err = gjson_hack.Int(sourceValue)
return val, err
case consts.DataTypeUint:
fallthrough
case consts.DataTypeUintPtr: // Uint类型
val, err := gjson_hack.Uint(sourceValue)
val, err = gjson_hack.Uint(sourceValue)
return val, err
case consts.DataTypeFloat:
fallthrough
case consts.DataTypeFloatPtr: // Float类型
val, err := gjson_hack.Float64(sourceValue)
val, err = gjson_hack.Float64(sourceValue)
return val, err
case consts.DataTypeString: // String类型
return sourceValue.String(), nil
case consts.DataTypeBool: // Bool类型
return sourceValue.Bool(), nil
case consts.DataTypeSliceFloat: // Float slice
val, err := gjson_hack.SliceFloat(sourceValue)
val, err = gjson_hack.SliceFloat(sourceValue)
return val, err
case consts.DataTypeSliceInt: // Int slice
val, err := gjson_hack.SliceInt(sourceValue)
val, err = gjson_hack.SliceInt(sourceValue)
return val, err
case consts.DataTypeSliceUint: // Uint slice
val, err := gjson_hack.SliceUint(sourceValue)
val, err = gjson_hack.SliceUint(sourceValue)
return val, err
case consts.DataTypeSliceString: // String slice
val, err := gjson_hack.SliceString(sourceValue)
val, err = gjson_hack.SliceString(sourceValue)
return val, err
case consts.DataTypeSliceBool: // Bool slice
val, err := gjson_hack.SliceBool(sourceValue)
val, err = gjson_hack.SliceBool(sourceValue)
return val, err
case consts.DataTypeMapStrAny: // Bool slice
val, err := gjson_hack.MapStrAny[any](sourceValue)
val, err = gjson_hack.MapStrAny[any](sourceValue)
return val, err
}
return sourceValue.Value(), nil
val = sourceValue.Value()
return val, nil
}
// 生成结构体的tag标签