123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- package assign
- import (
- "git.sxidc.com/go-tools/utils/reflectutils"
- "git.sxidc.com/go-tools/utils/strutils"
- "github.com/pkg/errors"
- "reflect"
- "strings"
- "time"
- )
- func DefaultUsage(from any, to any) error {
- return UseTag(from, to,
- func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, tag *Tag) error {
- if fromFieldElemValue.IsZero() {
- return nil
- }
- return defaultCallback(fromFieldElemValue, retFieldElementValue, tag)
- })
- }
- func defaultCallback(fromFieldElemValue reflect.Value, toFieldElemValue reflect.Value, tag *Tag) error {
- fromKind := reflectutils.GroupValueKind(fromFieldElemValue)
- toKind := reflectutils.GroupValueKind(toFieldElemValue)
- var fromAny any
- switch fromKind {
- case reflect.Struct:
- // time.Time类型的结构,接收字段是string类型,使用FormatTime的格式转换
- if reflectutils.IsValueTime(fromFieldElemValue) && toKind == reflect.String {
- fromString := fromFieldElemValue.Interface().(time.Time).Format(tag.TimeLayout)
- fromAny = trimFromString(fromString, tag)
- break
- }
- // 不是time.Time类型的结构,接收字段是结构,执行结构到结构字段的赋值
- if !reflectutils.IsValueTime(fromFieldElemValue) && toKind == reflect.Struct {
- return parseTag(fromFieldElemValue, &toFieldElemValue, func(fromFieldName string, fromFieldElemValue reflect.Value, toFieldElementValue reflect.Value, tag *Tag) error {
- return defaultCallback(fromFieldElemValue, toFieldElementValue, tag)
- })
- }
- // 直接将整个结构进行字段赋值
- fromAny = fromFieldElemValue.Interface()
- case reflect.Slice:
- fromFieldElementElemType := reflectutils.PointerTypeElem(fromFieldElemValue.Type().Elem())
- if fromFieldElementElemType.Kind() == reflect.String && toKind == reflect.String {
- stringSlice := make([]string, 0)
- for i := 0; i < fromFieldElemValue.Len(); i++ {
- stringSlice = append(stringSlice, reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(string))
- }
- fromString := strings.Join(stringSlice, tag.JoinWith)
- fromAny = trimFromString(fromString, tag)
- break
- }
- if fromFieldElementElemType.Kind() == reflect.Struct &&
- reflectutils.IsTypeTime(fromFieldElementElemType) &&
- toFieldElemValue.Type().Kind() == reflect.Slice &&
- reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem()).Kind() == reflect.String {
- stringSlice := make([]string, 0)
- for i := 0; i < fromFieldElemValue.Len(); i++ {
- fromString := reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(time.Time).Format(tag.TimeLayout)
- stringSlice = append(stringSlice, trimFromString(fromString, tag))
- }
- fromAny = stringSlice
- break
- }
- if fromFieldElementElemType.Kind() == reflect.String &&
- toFieldElemValue.Type().Kind() == reflect.Slice &&
- reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem()).Kind() == reflect.Struct &&
- reflectutils.IsTypeTime(reflectutils.PointerTypeElem(toFieldElemValue.Type().Elem())) {
- timeSlice := make([]time.Time, 0)
- for i := 0; i < fromFieldElemValue.Len(); i++ {
- timeParsed, err := time.ParseInLocation(tag.TimeLayout, reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(string), time.Local)
- if err != nil {
- return err
- }
- timeSlice = append(timeSlice, timeParsed)
- }
- fromAny = timeSlice
- break
- }
- fromAny = fromFieldElemValue.Interface()
- case reflect.String:
- fromString := fromFieldElemValue.String()
- if reflectutils.IsValueTime(toFieldElemValue) {
- toTimeField, err := time.ParseInLocation(tag.TimeLayout, fromString, time.Local)
- if err != nil {
- return err
- }
- fromAny = toTimeField
- break
- }
- if reflectutils.IsSliceValueOf(toFieldElemValue, reflect.String) {
- fromAny = strings.Split(fromString, tag.SplitWith)
- break
- }
- fromAny = trimFromString(fromString, tag)
- default:
- fromAny = fromFieldElemValue.Interface()
- }
- err := assignTo(toKind, fromAny, toFieldElemValue)
- if err != nil {
- return err
- }
- return nil
- }
- func assignTo(toKind reflect.Kind, fromAny any, toFieldElemValue reflect.Value) error {
- switch toKind {
- case reflect.Int64:
- return reflectutils.AssignInt64Value(fromAny, toFieldElemValue)
- case reflect.Uint64:
- return reflectutils.AssignUint64Value(fromAny, toFieldElemValue)
- case reflect.Float64:
- return reflectutils.AssignFloat64Value(fromAny, toFieldElemValue)
- case reflect.Bool:
- return reflectutils.AssignBoolValue(fromAny, toFieldElemValue)
- case reflect.String:
- return reflectutils.AssignStringValue(fromAny, toFieldElemValue)
- case reflect.Slice:
- return assignSlice(fromAny, toFieldElemValue)
- default:
- toFieldElemValue.Set(reflect.ValueOf(fromAny))
- return nil
- }
- }
- func trimFromString(fromString string, tag *Tag) string {
- if strutils.IsStringNotEmpty(tag.Trim) {
- return strings.Trim(fromString, tag.Trim)
- } else {
- if strutils.IsStringNotEmpty(tag.TrimPrefix) {
- return strings.TrimPrefix(fromString, tag.TrimPrefix)
- }
- if strutils.IsStringNotEmpty(tag.TrimSuffix) {
- return strings.TrimSuffix(fromString, tag.TrimSuffix)
- }
- }
- return fromString
- }
- func assignSlice(fromAny any, toFieldElemValue reflect.Value) error {
- fromElemValue := reflectutils.PointerValueElem(reflect.ValueOf(fromAny))
- if fromElemValue.Kind() != reflect.Slice {
- return errors.New("不支持的操作:试图将非slice类型字段赋值给slice类型字段")
- }
- if toFieldElemValue.Kind() != reflect.Slice {
- return errors.New("不支持的操作:试图将slice类型字段赋值给非slice类型字段")
- }
- // 构造slice
- sliceValue := reflect.MakeSlice(toFieldElemValue.Type(), 0, 0)
- // 遍历from slice
- for i := 0; i < fromElemValue.Len(); i++ {
- // 获取from slice中元素的Value
- fromElementValue := fromElemValue.Index(i)
- // 获取from slice中元素的ElemValue
- fromElementElemValue := reflectutils.PointerValueElem(fromElementValue)
- // 获取from slice中元素是nil指针
- if fromElementValue.Kind() == reflect.Pointer && fromElementValue.IsNil() {
- fromElementElemValue = reflect.New(fromElementElemValue.Type()).Elem()
- }
- if fromElementElemValue.Kind() == reflect.Slice {
- if toFieldElemValue.Type().Elem().Kind() != reflect.Slice {
- return errors.New("不支持的操作:试图将slice类型字段赋值给非slice类型字段")
- }
- toSliceElementValue := reflect.MakeSlice(toFieldElemValue.Type().Elem(), 0, 0)
- err := assignSlice(fromElementElemValue.Interface(), toSliceElementValue)
- if err != nil {
- return err
- }
- for j := 0; j < toSliceElementValue.Len(); j++ {
- if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
- sliceValue = reflect.Append(sliceValue, toSliceElementValue.Index(i).Addr())
- } else {
- sliceValue = reflect.Append(sliceValue, toSliceElementValue.Index(i))
- }
- }
- continue
- }
- var toElementElemValue reflect.Value
- if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
- if toFieldElemValue.Type().Elem().Elem().Kind() == fromElementElemValue.Kind() &&
- toFieldElemValue.Type().Elem().Elem().String() == fromElementElemValue.Type().String() {
- toElementElemValue = fromElementElemValue
- } else {
- toElementElemValue = reflect.New(toFieldElemValue.Type().Elem().Elem()).Elem()
- }
- } else {
- if toFieldElemValue.Type().Elem().Kind() == fromElementElemValue.Kind() &&
- toFieldElemValue.Type().Elem().String() == fromElementElemValue.String() {
- toElementElemValue = fromElementValue
- } else {
- toElementElemValue = reflect.New(toFieldElemValue.Type().Elem()).Elem()
- }
- }
- if fromElementElemValue.Kind() == reflect.Struct {
- if reflectutils.IsValueTime(fromElementElemValue) {
- if !reflectutils.IsValueTime(toElementElemValue) {
- return errors.New("无法从time.Time赋值到不是time.Time的结构")
- }
- if toElementElemValue.Type().Kind() == reflect.Pointer {
- toElementElemValue.Set(fromElementElemValue.Addr())
- } else {
- toElementElemValue.Set(fromElementElemValue)
- }
- } else {
- err := DefaultUsage(fromElementElemValue.Interface(), toElementElemValue.Addr().Interface())
- if err != nil {
- return err
- }
- }
- if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
- sliceValue = reflect.Append(sliceValue, toElementElemValue.Addr())
- } else {
- sliceValue = reflect.Append(sliceValue, toElementElemValue)
- }
- continue
- }
- toElementKind := reflectutils.GroupValueKind(toElementElemValue)
- err := assignTo(toElementKind, fromElementElemValue.Interface(), toElementElemValue)
- if err != nil {
- return err
- }
- if toFieldElemValue.Type().Elem().Kind() == reflect.Pointer {
- sliceValue = reflect.Append(sliceValue, toElementElemValue.Addr())
- } else {
- sliceValue = reflect.Append(sliceValue, toElementElemValue)
- }
- }
- toFieldElemValue.Set(sliceValue)
- return nil
- }
|