Skip to content

Commit

Permalink
Merge pull request #19 from devfeel/develop
Browse files Browse the repository at this point in the history
#### Version 0.7.7
Feature: add Object-oriented interface for the mapper.
comment: the old version implementation will be refactored in next release.
Tips: Thanks to @shyandsy
  • Loading branch information
devfeel authored Apr 15, 2022
2 parents afed01d + a6b4652 commit 28d634f
Show file tree
Hide file tree
Showing 14 changed files with 1,355 additions and 29 deletions.
70 changes: 68 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# devfeel/mapper

A simple and easy go tools for auto mapper struct to map, struct to struct, slice to slice, map to slice, map to json.

## 1. Install
Expand All @@ -8,6 +9,8 @@ go get -u github.com/devfeel/mapper
```

## 2. Getting Started

Traditional Usage
```go
package main

Expand Down Expand Up @@ -66,8 +69,8 @@ func main() {
fmt.Println("teacher", teacher)
fmt.Println("userMap:", userMap)
}

```

执行main,输出:
```
student: &{test 10 testId 100}
Expand All @@ -76,7 +79,59 @@ teacher &{test 10 testId }
userMap: &{map 10 x1asd 100 2017-11-20 13:45:56.3972504 +0800 CST m=+0.006004001}
```

Object Usage

```go
package main

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

type (
User struct {
Name string `json:"name" mapper:"name"`
Age int `json:"age" mapper:"age"`
}

Student struct {
Name string `json:"name" mapper:"name"`
Age int `json:"age" mapper:"-"`
}
)

func main() {
user := &User{Name: "test", Age: 10}
student := &Student{}

// create mapper object
m := mapper.NewMapper()

// enable the type checking
m.SetEnabledTypeChecking(true)

student.Age = 1

// disable the json tag
m.SetEnabledJsonTag(false)

// student::age should be 1
m.Mapper(user, student)

fmt.Println(student)
}
```

执行main,输出:
```
&{test 1}
```



## Features

* 支持不同结构体相同名称相同类型字段自动赋值,使用Mapper
* 支持不同结构体Slice的自动赋值,使用MapperSlice
* 支持字段为结构体时的自动赋值
Expand All @@ -88,4 +143,15 @@ userMap: &{map 10 x1asd 100 2017-11-20 13:45:56.3972504 +0800 CST m=+0.006004001
* 支持tag标签,tag关键字为 mapper
* 兼容json-tag标签
* 当tag为"-"时,将忽略tag定义,使用struct field name
* 无需手动Register struct,内部自动识别
* 无需手动Register struct,内部自动识别
* 支持开启关闭
* SetEnabledTypeChecking(bool) // 类型检查
* IsEnabledTypeChecking
* SetEnabledMapperTag // mapper tag
* IsEnabledMapperTag
* SetEnabledJsonTag // json tag
* IsEnabledJsonTag
* SetEnabledAutoTypeConvert // auto type convert
* IsEnabledAutoTypeConvert
* SetEnabledMapperStructField // mapper struct field
* IsEnabledMapperStructField
12 changes: 12 additions & 0 deletions constant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package mapper

const (
packageVersion = "0.7.6"
mapperTagKey = "mapper"
jsonTagKey = "json"
IgnoreTagValue = "-"
nameConnector = "_"
formatTime = "15:04:05"
formatDate = "2006-01-02"
formatDateTime = "2006-01-02 15:04:05"
)
5 changes: 3 additions & 2 deletions convert.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mapper

import (
"encoding/hex"
"fmt"
"math/big"
"reflect"
Expand All @@ -22,12 +23,12 @@ func (f *Convert) Set(v string) {

// Clear string
func (f *Convert) Clear() {
*f = Convert(0x1E)
*f = Convert(hex.EncodeToString([]byte{0x1E}))
}

// Exist check string exist
func (f Convert) Exist() bool {
return string(f) != string(0x1E)
return string(f) != hex.EncodeToString([]byte{0x1E})
}

// Bool string to bool
Expand Down
7 changes: 7 additions & 0 deletions example/object/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module object

go 1.16

replace github.com/devfeel/mapper v0.7.6 => ./../../../mapper

require github.com/devfeel/mapper v0.7.6
Empty file added example/object/go.sum
Empty file.
39 changes: 39 additions & 0 deletions example/object/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

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

type (
User struct {
Name string `json:"name" mapper:"name"`
Age int `json:"age" mapper:"age"`
}

Student struct {
Name string `json:"name" mapper:"name"`
Age int `json:"age" mapper:"-"`
}
)

func main() {
user := &User{Name: "test", Age: 10}
student := &Student{}

// create mapper object
m := mapper.NewMapper()

// enable the type checking
m.SetEnabledTypeChecking(true)

student.Age = 1

// disable the json tag
m.SetEnabledJsonTag(false)

// student::age should be 1
m.Mapper(user, student)

fmt.Println(student)
}
18 changes: 9 additions & 9 deletions example/typewrapper/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package main

import (
"fmt"
"github.com/devfeel/mapper"
"reflect"
"time"
)
Expand All @@ -28,7 +26,7 @@ type decimal struct {
}

type DecimalWrapper struct {
mapper.BaseTypeWrapper
// mapper.BaseTypeWrapper
}

func (w *DecimalWrapper) IsType(value reflect.Value) bool {
Expand All @@ -39,12 +37,14 @@ func (w *DecimalWrapper) IsType(value reflect.Value) bool {
}

func main() {
mapper.UseWrapper(&DecimalWrapper{})
user := &User{Name: "test", Age: 10, Score: decimal{value: 1}, Time: time.Now()}
stu := &Student{}
/*
mapper.UseWrapper(&DecimalWrapper{})
user := &User{Name: "test", Age: 10, Score: decimal{value: 1}, Time: time.Now()}
stu := &Student{}
mapper.AutoMapper(user, stu)
mapper.AutoMapper(user, stu)
fmt.Println(user)
fmt.Println(stu)
fmt.Println(user)
fmt.Println(stu)
*/
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module mapper

go 1.16

require github.com/devfeel/mapper v0.7.6
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/devfeel/mapper v0.7.6 h1:FItOzW4YpEp1x+U1izauW5+sbVIiymOwF7AiWxIdUVk=
github.com/devfeel/mapper v0.7.6/go.mod h1:foz4u16jrssGoDfnWYQGFcthjlU6uBV5UV8uYJfKneA=
52 changes: 36 additions & 16 deletions mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,36 @@ var (
typeWrappers []TypeWrapper
)

const (
packageVersion = "0.7.6"
mapperTagKey = "mapper"
jsonTagKey = "json"
IgnoreTagValue = "-"
nameConnector = "_"
formatTime = "15:04:05"
formatDate = "2006-01-02"
formatDateTime = "2006-01-02 15:04:05"
)
type IMapper interface {
Mapper(fromObj, toObj interface{}) error
AutoMapper(fromObj, toObj interface{}) error
MapperMap(fromMap map[string]interface{}, toObj interface{}) error
Register(obj interface{}) error
GetTypeName(obj interface{}) string
GetFieldName(objElem reflect.Value, index int) string
GetDefaultTimeWrapper() *TimeWrapper
CheckExistsField(elem reflect.Value, fieldName string) (realFieldName string, exists bool)
MapToSlice(fromMap map[string]interface{}, toSlice interface{}) error
MapperMapSlice(fromMaps map[string]map[string]interface{}, toSlice interface{}) error
MapperSlice(fromSlice, toSlice interface{}) error
MapToJson(fromMap map[string]interface{}) ([]byte, error)
JsonToMap(body []byte, toMap *map[string]interface{}) error

SetEnabledTypeChecking(isEnabled bool)
IsEnabledTypeChecking() bool

SetEnabledMapperTag(isEnabled bool)
IsEnabledMapperTag() bool

SetEnabledJsonTag(isEnabled bool)
IsEnabledJsonTag() bool

SetEnabledAutoTypeConvert(isEnabled bool)
IsEnabledAutoTypeConvert() bool

SetEnabledMapperStructField(isEnabled bool)
IsEnabledMapperStructField() bool
}

func init() {
ZeroValue = reflect.Value{}
Expand Down Expand Up @@ -136,7 +156,7 @@ func registerValue(objValue reflect.Value) error {
}
}

//store register flag
// store register flag
registerMap.Store(typeName, nil)
return nil
}
Expand Down Expand Up @@ -194,14 +214,14 @@ func MapperMap(fromMap map[string]interface{}, toObj interface{}) error {
if toElem == ZeroValue {
return errors.New("to obj is not legal value")
}
//check register flag
//if not register, register it
// check register flag
// if not register, register it
if !checkIsRegister(toElem) {
Register(toObj)
}
for k, v := range fromMap {
fieldName := k
//check field is exists
// check field is exists
realFieldName, exists := CheckExistsField(toElem, fieldName)
if !exists {
continue
Expand Down Expand Up @@ -274,7 +294,7 @@ func MapperMapSlice(fromMaps map[string]map[string]interface{}, toSlice interfac
toElemType := reflect.TypeOf(toSlice).Elem().Elem()
realType := toElemType.Kind()
direct := reflect.Indirect(toValue)
//3 elem parse: 1.[]*type 2.*type 3.type
// 3 elem parse: 1.[]*type 2.*type 3.type
if realType == reflect.Ptr {
toElemType = toElemType.Elem()
}
Expand Down Expand Up @@ -307,7 +327,7 @@ func MapperSlice(fromSlice, toSlice interface{}) error {
elemType := reflect.TypeOf(toSlice).Elem().Elem()
realType := elemType.Kind()
direct := reflect.Indirect(toValue)
//3 elem parse: 1.[]*type 2.*type 3.type
// 3 elem parse: 1.[]*type 2.*type 3.type
if realType == reflect.Ptr {
elemType = elemType.Elem()
}
Expand Down
Loading

0 comments on commit 28d634f

Please sign in to comment.