Эх сурвалжийг харах

完成assign tag的优化

yjp 4 сар өмнө
parent
commit
f4b86de05b

+ 19 - 10
framework/core/tag/assign/usage.go

@@ -44,19 +44,27 @@ func defaultCallback(fromFieldElemValue reflect.Value, toFieldElemValue reflect.
 		// 直接将整个结构进行字段赋值
 		fromAny = fromFieldElemValue.Interface()
 	case reflect.Slice:
-		if reflectutils.IsSliceValueOf(fromFieldElemValue, reflect.String) && toKind == reflect.String {
-			fromString := strings.Join(fromFieldElemValue.Interface().([]string), tag.JoinWith)
+		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 reflectutils.IsSliceValueOf(fromFieldElemValue, reflect.Struct) &&
-			reflectutils.IsTypeTime(fromFieldElemValue.Type().Elem()) &&
-			reflectutils.IsSliceValueOf(toFieldElemValue, reflect.String) {
+		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 := fromFieldElemValue.Index(i).Interface().(time.Time).Format(tag.TimeLayout)
+				fromString := reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(time.Time).Format(tag.TimeLayout)
 				stringSlice = append(stringSlice, trimFromString(fromString, tag))
 			}
 
@@ -64,13 +72,14 @@ func defaultCallback(fromFieldElemValue reflect.Value, toFieldElemValue reflect.
 			break
 		}
 
-		if reflectutils.IsSliceValueOf(fromFieldElemValue, reflect.String) &&
-			reflectutils.IsSliceValueOf(toFieldElemValue, reflect.Struct) &&
-			reflectutils.IsTypeTime(toFieldElemValue.Type().Elem()) {
+		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, fromFieldElemValue.Index(i).Interface().(string), time.Local)
+				timeParsed, err := time.ParseInLocation(tag.TimeLayout, reflectutils.PointerValueElem(fromFieldElemValue.Index(i)).Interface().(string), time.Local)
 				if err != nil {
 					return err
 				}

+ 182 - 108
test/assign_tag_test.go

@@ -732,69 +732,69 @@ func TestAssignTagDefaultUsage(t *testing.T) {
 }
 
 type AssignTagFromSlice struct {
-	BasicField                   string               `assign:"toField:BasicField"`
-	BasicSliceField              []string             `assign:"toField:BasicSliceField"`
-	TimeSliceField               []time.Time          `assign:"toField:TimeSliceField"`
-	StructSliceField             []AssignTagFrom      `assign:"toField:StructSliceField"`
-	MapSliceField                []map[string]string  `assign:"toField:MapSliceField"`
-	ChanSliceField               []chan any           `assign:"toField:ChanSliceField"`
-	FuncSliceField               []func() string      `assign:"toField:FuncSliceField"`
-	FromStringSliceToStringField []string             `assign:"toField:FromStringSliceToStringField"`
-	FromTimeToStringField        []time.Time          `assign:"toField:FromTimeToStringField"`
-	FromStringToTimeField        []string             `assign:"toField:FromStringToTimeField"`
-	BasicPointerSliceField       []*string            `assign:"toField:BasicPointerSliceField"`
-	TimePointerSliceField        []*time.Time         `assign:"toField:TimePointerSliceField"`
-	StructPointerSliceField      []*AssignTagFrom     `assign:"toField:StructPointerSliceField"`
-	MapPointerSliceField         []*map[string]string `assign:"toField:MapPointerSliceField"`
-	ChanPointerSliceField        []*chan any          `assign:"toField:ChanPointerSliceField"`
-	FuncPointerSliceField        []*func() string     `assign:"toField:FuncPointerSliceField"`
-	//FromStringSliceToStringPointerField []*string            `assign:"toField:FromStringSliceToStringPointerField"`
-	//FromTimeToStringPointerField        []*time.Time         `assign:"toField:FromTimeToStringPointerField"`
-	//FromStringToTimePointerField        []*string            `assign:"toField:FromStringToTimePointerField"`
+	BasicField                          string               `assign:"toField:BasicField"`
+	BasicSliceField                     []string             `assign:"toField:BasicSliceField"`
+	TimeSliceField                      []time.Time          `assign:"toField:TimeSliceField"`
+	StructSliceField                    []AssignTagFrom      `assign:"toField:StructSliceField"`
+	MapSliceField                       []map[string]string  `assign:"toField:MapSliceField"`
+	ChanSliceField                      []chan any           `assign:"toField:ChanSliceField"`
+	FuncSliceField                      []func() string      `assign:"toField:FuncSliceField"`
+	FromStringSliceToStringField        []string             `assign:"toField:FromStringSliceToStringField"`
+	FromTimeToStringField               []time.Time          `assign:"toField:FromTimeToStringField"`
+	FromStringToTimeField               []string             `assign:"toField:FromStringToTimeField"`
+	BasicPointerSliceField              []*string            `assign:"toField:BasicPointerSliceField"`
+	TimePointerSliceField               []*time.Time         `assign:"toField:TimePointerSliceField"`
+	StructPointerSliceField             []*AssignTagFrom     `assign:"toField:StructPointerSliceField"`
+	MapPointerSliceField                []*map[string]string `assign:"toField:MapPointerSliceField"`
+	ChanPointerSliceField               []*chan any          `assign:"toField:ChanPointerSliceField"`
+	FuncPointerSliceField               []*func() string     `assign:"toField:FuncPointerSliceField"`
+	FromStringSliceToStringPointerField []*string            `assign:"toField:FromStringSliceToStringPointerField"`
+	FromTimeToStringPointerField        []*time.Time         `assign:"toField:FromTimeToStringPointerField"`
+	FromStringToTimePointerField        []*string            `assign:"toField:FromStringToTimePointerField"`
 }
 
 type AssignTagFromSlicePointerField struct {
-	BasicField                   *string               `assign:"toField:BasicField"`
-	BasicSliceField              *[]string             `assign:"toField:BasicSliceField"`
-	TimeSliceField               *[]time.Time          `assign:"toField:TimeSliceField"`
-	StructSliceField             *[]AssignTagFrom      `assign:"toField:StructSliceField"`
-	MapSliceField                *[]map[string]string  `assign:"toField:MapSliceField"`
-	ChanSliceField               *[]chan any           `assign:"toField:ChanSliceField"`
-	FuncSliceField               *[]func() string      `assign:"toField:FuncSliceField"`
-	FromStringSliceToStringField *[]string             `assign:"toField:FromStringSliceToStringField"`
-	FromTimeToStringField        *[]time.Time          `assign:"toField:FromTimeToStringField"`
-	FromStringToTimeField        *[]string             `assign:"toField:FromStringToTimeField"`
-	BasicPointerSliceField       *[]*string            `assign:"toField:BasicPointerSliceField"`
-	TimePointerSliceField        *[]*time.Time         `assign:"toField:TimePointerSliceField"`
-	StructPointerSliceField      *[]*AssignTagFrom     `assign:"toField:StructPointerSliceField"`
-	MapPointerSliceField         *[]*map[string]string `assign:"toField:MapPointerSliceField"`
-	ChanPointerSliceField        *[]*chan any          `assign:"toField:ChanPointerSliceField"`
-	FuncPointerSliceField        *[]*func() string     `assign:"toField:FuncPointerSliceField"`
-	//FromStringSliceToStringPointerField *[]*string            `assign:"toField:FromStringSliceToStringPointerField"`
-	//FromTimeToStringPointerField        *[]*time.Time         `assign:"toField:FromTimeToStringPointerField"`
-	//FromStringToTimePointerField        *[]*string            `assign:"toField:FromStringToTimePointerField"`
+	BasicField                          *string               `assign:"toField:BasicField"`
+	BasicSliceField                     *[]string             `assign:"toField:BasicSliceField"`
+	TimeSliceField                      *[]time.Time          `assign:"toField:TimeSliceField"`
+	StructSliceField                    *[]AssignTagFrom      `assign:"toField:StructSliceField"`
+	MapSliceField                       *[]map[string]string  `assign:"toField:MapSliceField"`
+	ChanSliceField                      *[]chan any           `assign:"toField:ChanSliceField"`
+	FuncSliceField                      *[]func() string      `assign:"toField:FuncSliceField"`
+	FromStringSliceToStringField        *[]string             `assign:"toField:FromStringSliceToStringField"`
+	FromTimeToStringField               *[]time.Time          `assign:"toField:FromTimeToStringField"`
+	FromStringToTimeField               *[]string             `assign:"toField:FromStringToTimeField"`
+	BasicPointerSliceField              *[]*string            `assign:"toField:BasicPointerSliceField"`
+	TimePointerSliceField               *[]*time.Time         `assign:"toField:TimePointerSliceField"`
+	StructPointerSliceField             *[]*AssignTagFrom     `assign:"toField:StructPointerSliceField"`
+	MapPointerSliceField                *[]*map[string]string `assign:"toField:MapPointerSliceField"`
+	ChanPointerSliceField               *[]*chan any          `assign:"toField:ChanPointerSliceField"`
+	FuncPointerSliceField               *[]*func() string     `assign:"toField:FuncPointerSliceField"`
+	FromStringSliceToStringPointerField *[]*string            `assign:"toField:FromStringSliceToStringPointerField"`
+	FromTimeToStringPointerField        *[]*time.Time         `assign:"toField:FromTimeToStringPointerField"`
+	FromStringToTimePointerField        *[]*string            `assign:"toField:FromStringToTimePointerField"`
 }
 
 type AssignTagToSlice struct {
-	BasicField                   string
-	BasicSliceField              []string
-	TimeSliceField               []time.Time
-	StructSliceField             []AssignTagTo
-	MapSliceField                []map[string]string
-	ChanSliceField               []chan any
-	FuncSliceField               []func() string
-	FromStringSliceToStringField string
-	FromTimeToStringField        []string
-	FromStringToTimeField        []time.Time
-	BasicPointerSliceField       []*string
-	TimePointerSliceField        []*time.Time
-	StructPointerSliceField      []*AssignTagTo
-	MapPointerSliceField         []*map[string]string
-	ChanPointerSliceField        []*chan any
-	FuncPointerSliceField        []*func() string
-	//FromStringSliceToStringPointerField string
-	//FromTimeToStringPointerField []*string
-	//FromStringToTimePointerField []*time.Time
+	BasicField                          string
+	BasicSliceField                     []string
+	TimeSliceField                      []time.Time
+	StructSliceField                    []AssignTagTo
+	MapSliceField                       []map[string]string
+	ChanSliceField                      []chan any
+	FuncSliceField                      []func() string
+	FromStringSliceToStringField        string
+	FromTimeToStringField               []string
+	FromStringToTimeField               []time.Time
+	BasicPointerSliceField              []*string
+	TimePointerSliceField               []*time.Time
+	StructPointerSliceField             []*AssignTagTo
+	MapPointerSliceField                []*map[string]string
+	ChanPointerSliceField               []*chan any
+	FuncPointerSliceField               []*func() string
+	FromStringSliceToStringPointerField string
+	FromTimeToStringPointerField        []*string
+	FromStringToTimePointerField        []*time.Time
 }
 
 func (to AssignTagToSlice) checkFields(t *testing.T, from AssignTagFromSlice) {
@@ -903,6 +903,28 @@ func (to AssignTagToSlice) checkFields(t *testing.T, from AssignTagFromSlice) {
 				(*value)(), (*to.FuncPointerSliceField[i])()))
 		}
 	}
+
+	toStringSliceToStringSlice := strings.Split(to.FromStringSliceToStringPointerField, "::")
+	for i, value := range from.FromStringSliceToStringPointerField {
+		if *value != toStringSliceToStringSlice[i] {
+			t.Fatalf("%+v\n", errors.Errorf("FromStringSliceToStringPointerField not equal: from %v, to %v",
+				*value, toStringSliceToStringSlice[i]))
+		}
+	}
+
+	for i, value := range from.FromTimeToStringPointerField {
+		if value.Format(time.DateTime) != *to.FromTimeToStringPointerField[i] {
+			t.Fatalf("%+v\n", errors.Errorf("FromTimeToStringPointerField not equal: from %v, to %v",
+				value.Format(time.DateTime), *to.FromTimeToStringPointerField[i]))
+		}
+	}
+
+	for i, value := range from.FromStringToTimePointerField {
+		if *value != (*to.FromStringToTimePointerField[i]).Format(time.DateTime) {
+			t.Fatalf("%+v\n", errors.Errorf("FromStringToTimePointerField not equal: from %v, to %v",
+				*value, (*to.FromStringToTimePointerField[i]).Format(time.DateTime)))
+		}
+	}
 }
 
 func (to AssignTagToSlice) checkNil(t *testing.T) {
@@ -969,28 +991,40 @@ func (to AssignTagToSlice) checkNil(t *testing.T) {
 	if to.FuncPointerSliceField != nil {
 		t.Fatalf("%+v\n", errors.Errorf("FuncPointerSliceField not nil"))
 	}
+
+	if to.FromStringSliceToStringPointerField != "" {
+		t.Fatalf("%+v\n", errors.Errorf("FromStringSliceToStringPointerField not zero"))
+	}
+
+	if to.FromTimeToStringPointerField != nil {
+		t.Fatalf("%+v\n", errors.Errorf("FromTimeToStringPointerField not nil"))
+	}
+
+	if to.FromStringToTimePointerField != nil {
+		t.Fatalf("%+v\n", errors.Errorf("FromStringToTimePointerField not nil"))
+	}
 }
 
 type AssignTagToSlicePointerField struct {
-	BasicField                   *string
-	BasicSliceField              *[]string
-	TimeSliceField               *[]time.Time
-	StructSliceField             *[]AssignTagTo
-	MapSliceField                *[]map[string]string
-	ChanSliceField               *[]chan any
-	FuncSliceField               *[]func() string
-	FromStringSliceToStringField *string
-	FromTimeToStringField        *[]string
-	FromStringToTimeField        *[]time.Time
-	BasicPointerSliceField       *[]*string
-	TimePointerSliceField        *[]*time.Time
-	StructPointerSliceField      *[]*AssignTagTo
-	MapPointerSliceField         *[]*map[string]string
-	ChanPointerSliceField        *[]*chan any
-	FuncPointerSliceField        *[]*func() string
-	//FromStringSliceToStringPointerField *string
-	//FromTimeToStringPointerField *[]*string
-	//FromStringToTimePointerField *[]*time.Time
+	BasicField                          *string
+	BasicSliceField                     *[]string
+	TimeSliceField                      *[]time.Time
+	StructSliceField                    *[]AssignTagTo
+	MapSliceField                       *[]map[string]string
+	ChanSliceField                      *[]chan any
+	FuncSliceField                      *[]func() string
+	FromStringSliceToStringField        *string
+	FromTimeToStringField               *[]string
+	FromStringToTimeField               *[]time.Time
+	BasicPointerSliceField              *[]*string
+	TimePointerSliceField               *[]*time.Time
+	StructPointerSliceField             *[]*AssignTagTo
+	MapPointerSliceField                *[]*map[string]string
+	ChanPointerSliceField               *[]*chan any
+	FuncPointerSliceField               *[]*func() string
+	FromStringSliceToStringPointerField *string
+	FromTimeToStringPointerField        *[]*string
+	FromStringToTimePointerField        *[]*time.Time
 }
 
 func (to AssignTagToSlicePointerField) checkFields(t *testing.T, from AssignTagFromSlice) {
@@ -1099,6 +1133,28 @@ func (to AssignTagToSlicePointerField) checkFields(t *testing.T, from AssignTagF
 				(*value)(), (*(*to.FuncPointerSliceField)[i])()))
 		}
 	}
+
+	toStringSliceToStringSlice := strings.Split(*to.FromStringSliceToStringPointerField, "::")
+	for i, value := range from.FromStringSliceToStringPointerField {
+		if *value != toStringSliceToStringSlice[i] {
+			t.Fatalf("%+v\n", errors.Errorf("FromStringSliceToStringPointerField not equal: from %v, to %v",
+				*value, toStringSliceToStringSlice[i]))
+		}
+	}
+
+	for i, value := range from.FromTimeToStringPointerField {
+		if value.Format(time.DateTime) != *(*to.FromTimeToStringPointerField)[i] {
+			t.Fatalf("%+v\n", errors.Errorf("FromTimeToStringPointerField not equal: from %v, to %v",
+				value.Format(time.DateTime), *(*to.FromTimeToStringPointerField)[i]))
+		}
+	}
+
+	for i, value := range from.FromStringToTimePointerField {
+		if *value != (*to.FromStringToTimePointerField)[i].Format(time.DateTime) {
+			t.Fatalf("%+v\n", errors.Errorf("FromStringToTimePointerField not equal: from %v, to %v",
+				*value, (*to.FromStringToTimePointerField)[i].Format(time.DateTime)))
+		}
+	}
 }
 
 func (to AssignTagToSlicePointerField) checkNil(t *testing.T) {
@@ -1165,6 +1221,18 @@ func (to AssignTagToSlicePointerField) checkNil(t *testing.T) {
 	if to.FuncPointerSliceField != nil {
 		t.Fatalf("%+v\n", errors.Errorf("FuncPointerSliceField not nil"))
 	}
+
+	if to.FromStringSliceToStringPointerField != nil {
+		t.Fatalf("%+v\n", errors.Errorf("FuncPointerSliceField not nil"))
+	}
+
+	if to.FromTimeToStringPointerField != nil {
+		t.Fatalf("%+v\n", errors.Errorf("FromTimeToStringPointerField not nil"))
+	}
+
+	if to.FromStringToTimePointerField != nil {
+		t.Fatalf("%+v\n", errors.Errorf("FromStringToTimePointerField not nil"))
+	}
 }
 
 func TestAssignTagDefaultUsageSlice(t *testing.T) {
@@ -1244,43 +1312,49 @@ func TestAssignTagDefaultUsageSlice(t *testing.T) {
 	fromStringSliceToStringField := []string{str1, str2}
 	fromTimeToStringField := []time.Time{time1, time2}
 	fromStringToTimeField := []string{time1.Format(time.DateTime), time2.Format(time.DateTime)}
+	fromStringSliceToStringPointerField := []*string{&str1, &str2}
+	fromTimeToStringPointerField := []*time.Time{&time1, &time2}
 
 	from := AssignTagFromSlice{
-		BasicField:                   basicField,
-		BasicSliceField:              basicSliceField,
-		TimeSliceField:               timeSliceField,
-		StructSliceField:             structSliceField,
-		MapSliceField:                mapSliceField,
-		ChanSliceField:               chanSliceField,
-		FuncSliceField:               funcSliceField,
-		BasicPointerSliceField:       basicPointerSliceField,
-		TimePointerSliceField:        timePointerSliceField,
-		StructPointerSliceField:      structPointerSliceField,
-		MapPointerSliceField:         mapPointerSliceField,
-		ChanPointerSliceField:        chanPointerSliceField,
-		FuncPointerSliceField:        funcPointerSliceField,
-		FromStringSliceToStringField: fromStringSliceToStringField,
-		FromTimeToStringField:        fromTimeToStringField,
-		FromStringToTimeField:        fromStringToTimeField,
+		BasicField:                          basicField,
+		BasicSliceField:                     basicSliceField,
+		TimeSliceField:                      timeSliceField,
+		StructSliceField:                    structSliceField,
+		MapSliceField:                       mapSliceField,
+		ChanSliceField:                      chanSliceField,
+		FuncSliceField:                      funcSliceField,
+		FromStringSliceToStringField:        fromStringSliceToStringField,
+		FromTimeToStringField:               fromTimeToStringField,
+		FromStringToTimeField:               fromStringToTimeField,
+		BasicPointerSliceField:              basicPointerSliceField,
+		TimePointerSliceField:               timePointerSliceField,
+		StructPointerSliceField:             structPointerSliceField,
+		MapPointerSliceField:                mapPointerSliceField,
+		ChanPointerSliceField:               chanPointerSliceField,
+		FuncPointerSliceField:               funcPointerSliceField,
+		FromStringSliceToStringPointerField: fromStringSliceToStringPointerField,
+		FromTimeToStringPointerField:        fromTimeToStringPointerField,
 	}
 
 	fromPointer := AssignTagFromSlicePointerField{
-		BasicField:                   &basicField,
-		BasicSliceField:              &basicSliceField,
-		TimeSliceField:               &timeSliceField,
-		StructSliceField:             &structSliceField,
-		MapSliceField:                &mapSliceField,
-		ChanSliceField:               &chanSliceField,
-		FuncSliceField:               &funcSliceField,
-		BasicPointerSliceField:       &basicPointerSliceField,
-		TimePointerSliceField:        &timePointerSliceField,
-		StructPointerSliceField:      &structPointerSliceField,
-		MapPointerSliceField:         &mapPointerSliceField,
-		ChanPointerSliceField:        &chanPointerSliceField,
-		FuncPointerSliceField:        &funcPointerSliceField,
-		FromStringSliceToStringField: &fromStringSliceToStringField,
-		FromTimeToStringField:        &fromTimeToStringField,
-		FromStringToTimeField:        &fromStringToTimeField,
+		BasicField:                          &basicField,
+		BasicSliceField:                     &basicSliceField,
+		TimeSliceField:                      &timeSliceField,
+		StructSliceField:                    &structSliceField,
+		MapSliceField:                       &mapSliceField,
+		ChanSliceField:                      &chanSliceField,
+		FuncSliceField:                      &funcSliceField,
+		FromStringSliceToStringField:        &fromStringSliceToStringField,
+		FromTimeToStringField:               &fromTimeToStringField,
+		FromStringToTimeField:               &fromStringToTimeField,
+		BasicPointerSliceField:              &basicPointerSliceField,
+		TimePointerSliceField:               &timePointerSliceField,
+		StructPointerSliceField:             &structPointerSliceField,
+		MapPointerSliceField:                &mapPointerSliceField,
+		ChanPointerSliceField:               &chanPointerSliceField,
+		FuncPointerSliceField:               &funcPointerSliceField,
+		FromStringSliceToStringPointerField: &fromStringSliceToStringPointerField,
+		FromTimeToStringPointerField:        &fromTimeToStringPointerField,
 	}
 
 	fromPointerNil := AssignTagFromPointerField{}