Skip to content

Commit

Permalink
#### Version 0.7.4
Browse files Browse the repository at this point in the history
* Feature: AutoMapper&Mapper support mapper struct to map[string]interface{}
* Refactor: set MapperMapSlice to Deprecated, will remove on v1.0
* About AutoMapper::
  ```
  func Test_AutoMapper_StructToMap(t *testing.T) {
  	from := &FromStruct{Name: "From", Sex: true, AA: "AA"}
  	to := make(map[string]interface{})
  	err := AutoMapper(from, &to)
  	if err != nil {
  		t.Error("RunResult error: mapper error", err)
  	} else {
  		if to["UserName"] == "From"{
  			t.Log("RunResult success:", to)
  		}else{
  			t.Error("RunResult failed: map[UserName]", to["UserName"])
  		}
  	}
  }
  ```
* 2020-06-07 16:00 in ShangHai
  • Loading branch information
devfeel committed Jun 7, 2020
1 parent 7b11061 commit d082b55
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ userMap: &{map 10 x1asd 100 2017-11-20 13:45:56.3972504 +0800 CST m=+0.006004001
* 支持不同结构体相同名称相同类型字段自动赋值,使用Mapper
* 支持不同结构体Slice的自动赋值,使用MapperSlice
* 支持字段为结构体时的自动赋值
* 支持struct到map的自动映射赋值,使用Mapper
* 支持map到struct的自动映射赋值,使用MapperMap
* 支持map到struct slice的自动赋值,使用MapperMapSlice
* 支持map到struct slice的自动赋值,使用MapToSlice
* 支持map与json的互相转换
* 支持Time与Unix自动转换
* 支持tag标签,tag关键字为 mapper
Expand Down
14 changes: 8 additions & 6 deletions mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
)

const (
packageVersion = "0.6"
packageVersion = "0.7.4"
mapperTagKey = "mapper"
jsonTagKey = "json"
IgnoreTagValue = "-"
Expand Down Expand Up @@ -110,10 +110,12 @@ func registerValue(objValue reflect.Value) error {
}

typeName := regValue.Type().String()
for i := 0; i < regValue.NumField(); i++ {
mapFieldName := typeName + nameConnector + GetFieldName(regValue, i)
realFieldName := regValue.Type().Field(i).Name
fieldNameMap.Store(mapFieldName, realFieldName)
if regValue.Type().Kind() == reflect.Struct {
for i := 0; i < regValue.NumField(); i++ {
mapFieldName := typeName + nameConnector + GetFieldName(regValue, i)
realFieldName := regValue.Type().Field(i).Name
fieldNameMap.Store(mapFieldName, realFieldName)
}
}

//store register flag
Expand Down Expand Up @@ -240,7 +242,7 @@ func MapToSlice(fromMap map[string]interface{}, toSlice interface{}) error {

// MapperMapSlice mapper from map[string]map[string]interface{} to a slice of any type's ptr
// toSlice must be a slice of any type.
// Deprecated: Use the PostFormValue instead
// Deprecated: will remove on v1.0, please use MapToSlice instead
func MapperMapSlice(fromMaps map[string]map[string]interface{}, toSlice interface{}) error {
var err error
toValue := reflect.ValueOf(toSlice)
Expand Down
18 changes: 17 additions & 1 deletion mapper_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ func elemMapper(fromElem, toElem reflect.Value) error {
if !checkIsRegister(toElem) {
registerValue(toElem)
}
if toElem.Type().Kind() == reflect.Map {
elemToMap(fromElem, toElem)
} else {
elemToStruct(fromElem, toElem)
}

return nil
}

func elemToStruct(fromElem, toElem reflect.Value) {
for i := 0; i < fromElem.NumField(); i++ {
fromFieldInfo := fromElem.Field(i)
fieldName := GetFieldName(fromElem, i)
Expand Down Expand Up @@ -64,7 +73,14 @@ func elemMapper(fromElem, toElem reflect.Value) error {
}

}
return nil
}

func elemToMap(fromElem, toElem reflect.Value) {
for i := 0; i < fromElem.NumField(); i++ {
fromFieldInfo := fromElem.Field(i)
fieldName := GetFieldName(fromElem, i)
toElem.SetMapIndex(reflect.ValueOf(fieldName), fromFieldInfo)
}
}

func setFieldValue(fieldValue reflect.Value, fieldKind reflect.Kind, value interface{}) error {
Expand Down
24 changes: 24 additions & 0 deletions mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,21 @@ func Test_AutoMapper(t *testing.T) {
}
}

func Test_AutoMapper_StructToMap(t *testing.T) {
from := &FromStruct{Name: "From", Sex: true, AA: "AA"}
to := make(map[string]interface{})
err := AutoMapper(from, &to)
if err != nil {
t.Error("RunResult error: mapper error", err)
} else {
if to["UserName"] == "From" {
t.Log("RunResult success:", to)
} else {
t.Error("RunResult failed: map[UserName]", to["UserName"])
}
}
}

func Test_MapperMap(t *testing.T) {
validateTime, _ := time.Parse("2006-01-02 15:04:05", "2017-01-01 10:00:00")
fromMap := make(map[string]interface{})
Expand Down Expand Up @@ -319,6 +334,15 @@ func BenchmarkAutoMapper(b *testing.B) {
}
}

func BenchmarkAutoMapper_Map(b *testing.B) {
from := &FromStruct{Name: "From", Sex: true, AA: "AA"}
to := make(map[string]interface{})

for i := 0; i < b.N; i++ {
Mapper(from, &to)
}
}

func BenchmarkMapperMap(b *testing.B) {
Register(&testStruct{})
fromMap := make(map[string]interface{})
Expand Down
23 changes: 23 additions & 0 deletions version.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
## devfeel/mapper


#### Version 0.7.4
* Feature: AutoMapper&Mapper support mapper struct to map[string]interface{}
* Refactor: set MapperMapSlice to Deprecated, will remove on v1.0
* About AutoMapper::
```
func Test_AutoMapper_StructToMap(t *testing.T) {
from := &FromStruct{Name: "From", Sex: true, AA: "AA"}
to := make(map[string]interface{})
err := AutoMapper(from, &to)
if err != nil {
t.Error("RunResult error: mapper error", err)
} else {
if to["UserName"] == "From"{
t.Log("RunResult success:", to)
}else{
t.Error("RunResult failed: map[UserName]", to["UserName"])
}
}
}
```
* 2020-06-07 16:00 in ShangHai

#### Version 0.7.3
* Feature: add MapToSlice to mapper from map[string]interface{} to a slice of any type's ptr
* Refactor: set MapperMapSlice to Deprecated, will remove on v1.0
Expand Down

0 comments on commit d082b55

Please sign in to comment.