123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package assign
- import (
- "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
- "git.sxidc.com/go-tools/utils/reflectutils"
- "git.sxidc.com/go-tools/utils/strutils"
- "github.com/pkg/errors"
- "reflect"
- "strings"
- "time"
- )
- const (
- defaultStringSliceSeparator = "::"
- tagPartSeparator = ";"
- tagPartKeyValueSeparator = ":"
- )
- const (
- tagKey = "assign"
- tagPartIgnore = "-"
- tagPartToPackage = "toPackage"
- tagPartToStruct = "toStruct"
- tagPartToField = "toField"
- tagPartTimeLayout = "timeLayout"
- tagPartJoinWith = "joinWith"
- tagPartSplitWith = "splitWith"
- tagPartTrim = "trim"
- tagPartTrimPrefix = "trimPrefix"
- tagPartTrimSuffix = "trimSuffix"
- )
- type Tag struct {
- ToPackage string
- ToStruct string
- ToField string
- TimeLayout string
- JoinWith string
- SplitWith string
- Trim string
- TrimPrefix string
- TrimSuffix string
- }
- func parseTag(fromElemValue reflect.Value, toElemValue *reflect.Value, onParsedFieldTagFunc OnParsedFieldTagCallback) error {
- for i := 0; i < fromElemValue.NumField(); i++ {
- fromField := fromElemValue.Type().Field(i)
- fromFieldValue := fromElemValue.Field(i)
- // 无效值
- if !fromFieldValue.IsValid() {
- continue
- }
- fromFieldElemValue := reflectutils.PointerValueElem(fromFieldValue)
- if fromFieldValue.Kind() == reflect.Pointer && fromFieldValue.IsNil() {
- fromFieldElemValue = reflect.New(fromFieldValue.Type().Elem()).Elem()
- }
- tagStr := fromField.Tag.Get(tagKey)
- // 结构类型的字段上没有添加Tag, 先尝试直接按照字段赋值
- if strutils.IsStringEmpty(tagStr) && fromFieldElemValue.Kind() == reflect.Struct &&
- !reflectutils.IsValueTime(fromFieldElemValue) {
- err := parseTag(fromFieldElemValue, toElemValue, onParsedFieldTagFunc)
- if err != nil {
- return err
- }
- continue
- }
- tag, err := parseFieldTag(fromField, tagStr)
- if err != nil {
- return err
- }
- if tag == nil {
- continue
- }
- if (strutils.IsStringNotEmpty(tag.ToPackage) && toElemValue.Type().PkgPath() != tag.ToPackage) ||
- (strutils.IsStringNotEmpty(tag.ToStruct) && toElemValue.Type().Name() != tag.ToStruct) {
- continue
- }
- toFieldValue := toElemValue.FieldByName(tag.ToField)
- // 不存在对应的字段
- if !toFieldValue.IsValid() {
- continue
- }
- toFieldElemValue := toFieldValue
- if toFieldValue.Kind() == reflect.Pointer {
- if fromFieldValue.Kind() == reflect.Pointer && fromFieldValue.IsNil() {
- continue
- }
- if !toFieldValue.IsValid() {
- continue
- }
- if !toFieldValue.CanSet() {
- continue
- }
- // 空值针,初始化
- if toFieldValue.IsNil() {
- toFieldValue.Set(reflect.New(toFieldValue.Type().Elem()))
- }
- toFieldElemValue = toFieldValue.Elem()
- }
- err = onParsedFieldTagFunc(fromField.Name, fromFieldElemValue, toFieldElemValue, tag)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func parseFieldTag(field reflect.StructField, tagStr string) (*Tag, error) {
- if tagStr == tagPartIgnore {
- return nil, nil
- }
- tag := &Tag{
- ToPackage: "",
- ToStruct: "",
- ToField: field.Name,
- TimeLayout: time.DateTime,
- JoinWith: defaultStringSliceSeparator,
- SplitWith: defaultStringSliceSeparator,
- Trim: "",
- TrimPrefix: "",
- TrimSuffix: "",
- }
- if strutils.IsStringEmpty(tagStr) {
- return tag, nil
- }
- tagParts := strings.Split(tagStr, tagPartSeparator)
- if tagParts != nil || len(tagParts) != 0 {
- for _, tagPart := range tagParts {
- tagPartKeyValue := strings.SplitN(strings.TrimSpace(tagPart), tagPartKeyValueSeparator, 2)
- if tagPartKeyValue != nil && len(tagPartKeyValue) == 2 && strutils.IsStringNotEmpty(tagPartKeyValue[1]) {
- tagPartKeyValue[1] = strings.Trim(tagPartKeyValue[1], "'")
- }
- if strutils.IsStringEmpty(tagPartKeyValue[0]) {
- continue
- }
- switch tagPartKeyValue[0] {
- case tagPartToPackage:
- tag.ToStruct = tagPartKeyValue[1]
- case tagPartToStruct:
- tag.ToStruct = tagPartKeyValue[1]
- case tagPartToField:
- tag.ToField = tagPartKeyValue[1]
- case tagPartTimeLayout:
- tag.TimeLayout = tagPartKeyValue[1]
- case tagPartJoinWith:
- if strutils.IsStringEmpty(tagPartKeyValue[1]) {
- return nil, errors.New(tagPartJoinWith + "没有赋值分隔符")
- }
- tag.JoinWith = tagPartKeyValue[1]
- case tagPartSplitWith:
- if strutils.IsStringEmpty(tagPartKeyValue[1]) {
- return nil, errors.New(tagPartSplitWith + "没有赋值分隔符")
- }
- tag.SplitWith = tagPartKeyValue[1]
- case tagPartTrim:
- tag.Trim = tagPartKeyValue[1]
- case tagPartTrimPrefix:
- tag.TrimPrefix = tagPartKeyValue[1]
- case tagPartTrimSuffix:
- tag.TrimSuffix = tagPartKeyValue[1]
- default:
- err := errors.New(tagKey + "不支持的tag: " + tagPartKeyValue[0])
- logger.GetInstance().Error(err)
- continue
- }
- }
- }
- return tag, nil
- }
|