Skip to content

Commit

Permalink
Merge pull request #41 from devfeel/master
Browse files Browse the repository at this point in the history
#### Version 0.7.14
  • Loading branch information
devfeel authored Sep 6, 2024
2 parents 8360d9a + 347b0c0 commit f12b58f
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 59 deletions.
2 changes: 1 addition & 1 deletion constant.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mapper

const (
packageVersion = "0.7.13"
packageVersion = "0.7.14"
mapperTagKey = "mapper"
jsonTagKey = "json"
IgnoreTagValue = "-"
Expand Down
59 changes: 59 additions & 0 deletions example/newmapper/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package main

import (
"fmt"
"github.com/devfeel/mapper"
"time"
)

type (
User struct {
Name string
Age int `mapper:"_Age"`
Id string `mapper:"_id"`
AA string `json:"Score,omitempty"`
Data []byte
Students []Student
Time time.Time
}

Student struct {
Name string
Age int
Id string `mapper:"_id"`
Score string
}

Teacher struct {
Name string
Age int
Id string `mapper:"_id"`
Level string
}
)

func main() {
user := &User{}
userMap := &User{}
teacher := &Teacher{}
student := &Student{Name: "test", Age: 10, Id: "testId", Score: "100"}
valMap := make(map[string]interface{})
valMap["Name"] = "map"
valMap["Age"] = 10
valMap["_id"] = "x1asd"
valMap["Score"] = 100
valMap["Data"] = []byte{1, 2, 3, 4}
valMap["Students"] = []byte{1, 2, 3, 4} //[]Student{*student}
valMap["Time"] = time.Now()

mp := mapper.NewMapper(mapper.CTypeChecking(true), mapper.CMapperTag(true))

mp.Mapper(student, user)
mp.AutoMapper(student, teacher)
mp.MapperMap(valMap, userMap)

fmt.Println("student:", student)
fmt.Println("user:", user)
fmt.Println("teacher", teacher)
fmt.Println("userMap:", userMap)
}
1 change: 1 addition & 0 deletions mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type IMapper interface {

GetTypeName(obj interface{}) string
GetFieldName(objElem reflect.Value, index int) string
GetCustomTagName() string
GetDefaultTimeWrapper() *TimeWrapper

CheckExistsField(elem reflect.Value, fieldName string) (realFieldName string, exists bool)
Expand Down
88 changes: 38 additions & 50 deletions mapper_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,25 @@ import (
)

type mapperObject struct {
ZeroValue reflect.Value
DefaultTimeWrapper *TimeWrapper
typeWrappers []TypeWrapper
timeType reflect.Type
jsonTimeType reflect.Type
fieldNameMap sync.Map
registerMap sync.Map
enabledTypeChecking bool
enabledMapperStructField bool
enabledAutoTypeConvert bool
enabledMapperTag bool
enabledJsonTag bool

enabledCustomTag bool
customTagName string

// in the version < 0.7.8, we use field name as the key when mapping structs if field tag is "-"
// from 0.7.8, we add switch enableIgnoreFieldTag which is false in default
// if caller enable this flag, the field will be ignored in the mapping process
enableFieldIgnoreTag bool
}

func NewMapper() IMapper {
ZeroValue reflect.Value
DefaultTimeWrapper *TimeWrapper
typeWrappers []TypeWrapper
timeType reflect.Type
jsonTimeType reflect.Type
fieldNameMap sync.Map
registerMap sync.Map
setting *Setting
}

func NewMapper(opts ...Option) IMapper {
setting := NewSetting(opts...)
dm := mapperObject{
ZeroValue: reflect.Value{},
DefaultTimeWrapper: NewTimeWrapper(),
typeWrappers: []TypeWrapper{},
timeType: reflect.TypeOf(time.Now()),
jsonTimeType: reflect.TypeOf(JSONTime(time.Now())),
enabledTypeChecking: false,
enabledMapperStructField: true,
enabledAutoTypeConvert: true,
enabledMapperTag: true,
enabledJsonTag: true,
enabledCustomTag: false,
enableFieldIgnoreTag: false, // 保留老版本默认行为:对于tag = “-”的字段使用FieldName
ZeroValue: reflect.Value{},
DefaultTimeWrapper: NewTimeWrapper(),
typeWrappers: []TypeWrapper{},
timeType: reflect.TypeOf(time.Now()),
jsonTimeType: reflect.TypeOf(JSONTime(time.Now())),
setting: setting,
}
dm.useWrapper(dm.DefaultTimeWrapper)
return &dm
Expand Down Expand Up @@ -122,46 +105,46 @@ func (dm *mapperObject) MapperMap(fromMap map[string]interface{}, toObj interfac
// if set true, the field type will be checked for consistency during mapping
// default is false
func (dm *mapperObject) SetEnabledTypeChecking(isEnabled bool) {
dm.enabledTypeChecking = isEnabled
dm.setting.EnabledTypeChecking = isEnabled
}

func (dm *mapperObject) IsEnabledTypeChecking() bool {
return dm.enabledTypeChecking
return dm.setting.EnabledTypeChecking
}

// SetEnabledMapperTag set enabled flag for 'Mapper' tag check
// if set true, 'Mapper' tag will be check during mapping's GetFieldName
// default is true
func (dm *mapperObject) SetEnabledMapperTag(isEnabled bool) {
dm.enabledMapperTag = isEnabled
dm.setting.EnabledMapperTag = isEnabled
dm.cleanRegisterValue()
}

func (dm *mapperObject) IsEnabledMapperTag() bool {
return dm.enabledMapperTag
return dm.setting.EnabledMapperTag
}

// SetEnabledJsonTag set enabled flag for 'Json' tag check
// if set true, 'Json' tag will be check during mapping's GetFieldName
// default is true
func (dm *mapperObject) SetEnabledJsonTag(isEnabled bool) {
dm.enabledJsonTag = isEnabled
dm.setting.EnabledJsonTag = isEnabled
dm.cleanRegisterValue()
}

func (dm *mapperObject) IsEnabledJsonTag() bool {
return dm.enabledJsonTag
return dm.setting.EnabledJsonTag
}

// SetEnabledAutoTypeConvert set enabled flag for auto type convert
// if set true, field will auto convert in Time and Unix
// default is true
func (dm *mapperObject) SetEnabledAutoTypeConvert(isEnabled bool) {
dm.enabledAutoTypeConvert = isEnabled
dm.setting.EnabledAutoTypeConvert = isEnabled
}

func (dm *mapperObject) IsEnabledAutoTypeConvert() bool {
return dm.enabledAutoTypeConvert
return dm.setting.EnabledAutoTypeConvert
}

// SetEnabledMapperStructField set enabled flag for MapperStructField
Expand All @@ -171,40 +154,40 @@ func (dm *mapperObject) IsEnabledAutoTypeConvert() bool {
// 2. fromField and toField must be not same type
// default is enabled
func (dm *mapperObject) SetEnabledMapperStructField(isEnabled bool) {
dm.enabledMapperStructField = isEnabled
dm.setting.EnabledMapperStructField = isEnabled
}

func (dm *mapperObject) IsEnabledMapperStructField() bool {
return dm.enabledMapperStructField
return dm.setting.EnabledMapperStructField
}

// SetEnabledCustomTag set enabled flag for set custom tag name
// if set true and set customTagName, the custom tag will be check during mapping's GetFieldName
// default is false
func (dm *mapperObject) SetEnabledCustomTag(isEnabled bool) {
dm.enabledCustomTag = isEnabled
dm.setting.EnabledCustomTag = isEnabled
dm.cleanRegisterValue()
}

func (dm *mapperObject) IsEnabledCustomTag() bool {
return dm.enabledCustomTag
return dm.setting.EnabledCustomTag
}

// SetCustomTagName
func (dm *mapperObject) SetCustomTagName(tagName string) {
dm.customTagName = tagName
dm.setting.CustomTagName = tagName
}

// SetEnableFieldIgnoreTag set the enabled flag for the ignored tag
// in the version < 0.7.8, we use field name as the key when mapping structs if field tag is "-"
// from 0.7.8, we add switch enableFieldIgnoreTag which is false in default
// if caller enable this flag, the field will be ignored in the mapping process
func (dm *mapperObject) SetEnableFieldIgnoreTag(isEnabled bool) {
dm.enableFieldIgnoreTag = isEnabled
dm.setting.EnableFieldIgnoreTag = isEnabled
}

func (dm *mapperObject) IsEnableFieldIgnoreTag() bool {
return dm.enableFieldIgnoreTag
return dm.setting.EnableFieldIgnoreTag
}

// GetTypeName get type name
Expand All @@ -213,6 +196,11 @@ func (dm *mapperObject) GetTypeName(obj interface{}) string {
return object.String()
}

// GetCustomTagName get CustomTagName
func (dm *mapperObject) GetCustomTagName() string {
return dm.setting.CustomTagName
}

// GetFieldName get fieldName with ElemValue and index
// if config tag string, return tag value
func (dm *mapperObject) GetFieldName(objElem reflect.Value, index int) string {
Expand Down
16 changes: 8 additions & 8 deletions mapper_object_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ func (dm *mapperObject) convertstructfieldInternal(fieldName string, fromFieldIn

toFieldInfo := toElem.FieldByName(realFieldName)
// check field is same type
if dm.enabledTypeChecking {
if dm.setting.EnabledTypeChecking {
if fromFieldInfo.Kind() != toFieldInfo.Kind() {
return nil
}
}

if dm.enabledMapperStructField &&
if dm.setting.EnabledMapperStructField &&
toFieldInfo.Kind() == reflect.Struct && fromFieldInfo.Kind() == reflect.Struct &&
toFieldInfo.Type() != fromFieldInfo.Type() &&
!dm.checkIsTypeWrapper(toFieldInfo) && !dm.checkIsTypeWrapper(fromFieldInfo) {
Expand All @@ -154,7 +154,7 @@ func (dm *mapperObject) convertstructfieldInternal(fieldName string, fromFieldIn
}
} else {
isSet := false
if dm.enabledAutoTypeConvert {
if dm.setting.EnabledAutoTypeConvert {
if dm.DefaultTimeWrapper.IsType(fromFieldInfo) && toFieldInfo.Kind() == reflect.Int64 {
fromTime := fromFieldInfo.Interface().(time.Time)
toFieldInfo.Set(reflect.ValueOf(TimeToUnix(fromTime)))
Expand Down Expand Up @@ -263,7 +263,7 @@ func (dm *mapperObject) setFieldValue(fieldValue reflect.Value, fieldKind reflec
case string:
timeString = d
case int64:
if dm.enabledAutoTypeConvert {
if dm.setting.EnabledAutoTypeConvert {
// try to transform Unix time to local Time
t, err := UnixToTimeLocation(value.(int64), time.UTC.String())
if err != nil {
Expand Down Expand Up @@ -303,15 +303,15 @@ func (dm *mapperObject) setFieldValue(fieldValue reflect.Value, fieldKind reflec
func (dm *mapperObject) getStructTag(field reflect.StructField) string {
tagValue := ""
// 1.check mapperTagKey
if dm.enabledMapperTag {
if dm.setting.EnabledMapperTag {
tagValue = field.Tag.Get(mapperTagKey)
if tagValue != "" {
return tagValue
}
}

// 2.check jsonTagKey
if dm.enabledJsonTag {
if dm.setting.EnabledJsonTag {
tagValue = field.Tag.Get(jsonTagKey)
if tagValue != "" {
// support more tag property, as json tag omitempty 2018-07-13
Expand All @@ -321,8 +321,8 @@ func (dm *mapperObject) getStructTag(field reflect.StructField) string {

// 3.che
// ck customTag
if dm.enabledCustomTag {
tagValue = field.Tag.Get(dm.customTagName)
if dm.setting.EnabledCustomTag {
tagValue = field.Tag.Get(dm.setting.CustomTagName)
if tagValue != "" {
return tagValue
}
Expand Down
6 changes: 6 additions & 0 deletions mapper_object_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package mapper

import (
"fmt"
"reflect"
"strconv"
"sync"
"testing"
"time"
)

func TestMapperObject_NewMapper(t *testing.T) {
m := NewMapper(CTypeChecking(true), CCustomTagName("^"))
fmt.Println(m)
}

func Test_Object_SetEnabledTypeChecking(t *testing.T) {
m := NewMapper()
m.SetEnabledTypeChecking(true)
Expand Down
Loading

0 comments on commit f12b58f

Please sign in to comment.