feat: refactor type mapper.
This commit is contained in:
@@ -17,26 +17,26 @@ func main() {
|
|||||||
Age int
|
Age int
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModelType struct {
|
type EntityType struct {
|
||||||
Name string
|
Name string
|
||||||
Age int
|
Age int
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper := mapper.NewCopierMapper[DtoType, ModelType]()
|
mapper := mapper.NewCopierMapper[DtoType, EntityType]()
|
||||||
|
|
||||||
// 测试 ToModel 方法
|
// 测试 ToEntity 方法
|
||||||
dto := &DtoType{Name: "Alice", Age: 25}
|
dto := &DtoType{Name: "Alice", Age: 25}
|
||||||
model := mapper.ToModel(dto)
|
entity := mapper.ToEntity(dto)
|
||||||
|
|
||||||
// 测试 ToModel 方法,传入 nil
|
// 测试 ToEntity 方法,传入 nil
|
||||||
modelNil := mapper.ToModel(nil)
|
entityNil := mapper.ToEntity(nil)
|
||||||
|
|
||||||
// 测试 ToDto 方法
|
// 测试 ToDTO 方法
|
||||||
model = &ModelType{Name: "Bob", Age: 30}
|
entity = &EntityType{Name: "Bob", Age: 30}
|
||||||
dtoResult := mapper.ToDto(model)
|
dtoResult := mapper.ToDTO(entity)
|
||||||
|
|
||||||
// 测试 ToDto 方法,传入 nil
|
// 测试 ToDTO 方法,传入 nil
|
||||||
dtoNil := mapper.ToDto(nil)
|
dtoNil := mapper.ToDTO(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -50,7 +50,7 @@ import "github.com/tx7do/go-utils/mapper"
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
type DtoType int32
|
type DtoType int32
|
||||||
type ModelType string
|
type EntityType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DtoTypeOne DtoType = 1
|
DtoTypeOne DtoType = 1
|
||||||
@@ -58,8 +58,8 @@ func main() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ModelTypeOne ModelType = "One"
|
EntityTypeOne EntityType = "One"
|
||||||
ModelTypeTwo ModelType = "Two"
|
EntityTypeTwo EntityType = "Two"
|
||||||
)
|
)
|
||||||
|
|
||||||
nameMap := map[int32]string{
|
nameMap := map[int32]string{
|
||||||
@@ -71,25 +71,25 @@ func main() {
|
|||||||
"Two": 2,
|
"Two": 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
converter := mapper.NewEnumTypeConverter[DtoType, ModelType](nameMap, valueMap)
|
converter := mapper.NewEnumTypeConverter[DtoType, EntityType](nameMap, valueMap)
|
||||||
|
|
||||||
// 测试 ToModel 方法
|
// 测试 ToEntity 方法
|
||||||
dto := DtoTypeOne
|
dto := DtoTypeOne
|
||||||
model := converter.ToModel(&dto)
|
entity := converter.ToEntity(&dto)
|
||||||
|
|
||||||
// 测试 ToModel 方法,传入不存在的值
|
// 测试 ToEntity 方法,传入不存在的值
|
||||||
dtoInvalid := DtoType(3)
|
dtoInvalid := DtoType(3)
|
||||||
modelInvalid := converter.ToModel(&dtoInvalid)
|
entityInvalid := converter.ToEntity(&dtoInvalid)
|
||||||
|
|
||||||
// 测试 ToDto 方法
|
// 测试 ToDTO 方法
|
||||||
tmpModelTwo := ModelTypeTwo
|
tmpEntityTwo := EntityTypeTwo
|
||||||
model = &tmpModelTwo
|
entity = &tmpEntityTwo
|
||||||
dtoResult := converter.ToDto(model)
|
dtoResult := converter.ToDTO(entity)
|
||||||
|
|
||||||
// 测试 ToDto 方法,传入不存在的值
|
// 测试 ToDTO 方法,传入不存在的值
|
||||||
tmpModelThree := ModelType("Three")
|
tmpEntityThree := EntityType("Three")
|
||||||
modelInvalid = &tmpModelThree
|
entityInvalid = &tmpEntityThree
|
||||||
dtoInvalidResult := converter.ToDto(modelInvalid)
|
dtoInvalidResult := converter.ToDTO(entityInvalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,19 +4,22 @@ import (
|
|||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EnumTypeConverter[DTO ~int32, MODEL ~string] struct {
|
type EnumTypeConverter[DTO ~int32, ENTITY ~string] struct {
|
||||||
nameMap map[int32]string
|
nameMap map[int32]string
|
||||||
valueMap map[string]int32
|
valueMap map[string]int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnumTypeConverter[DTO ~int32, MODEL ~string](nameMap map[int32]string, valueMap map[string]int32) *EnumTypeConverter[DTO, MODEL] {
|
func NewEnumTypeConverter[DTO ~int32, ENTITY ~string](
|
||||||
return &EnumTypeConverter[DTO, MODEL]{
|
nameMap map[int32]string,
|
||||||
|
valueMap map[string]int32,
|
||||||
|
) *EnumTypeConverter[DTO, ENTITY] {
|
||||||
|
return &EnumTypeConverter[DTO, ENTITY]{
|
||||||
valueMap: valueMap,
|
valueMap: valueMap,
|
||||||
nameMap: nameMap,
|
nameMap: nameMap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *EnumTypeConverter[DTO, MODEL]) ToModel(dto *DTO) *MODEL {
|
func (m *EnumTypeConverter[DTO, ENTITY]) ToEntity(dto *DTO) *ENTITY {
|
||||||
if dto == nil {
|
if dto == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -26,16 +29,16 @@ func (m *EnumTypeConverter[DTO, MODEL]) ToModel(dto *DTO) *MODEL {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
model := MODEL(find)
|
entity := ENTITY(find)
|
||||||
return &model
|
return &entity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *EnumTypeConverter[DTO, MODEL]) ToDto(model *MODEL) *DTO {
|
func (m *EnumTypeConverter[DTO, ENTITY]) ToDTO(entity *ENTITY) *DTO {
|
||||||
if model == nil {
|
if entity == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
find, ok := m.valueMap[string(*model)]
|
find, ok := m.valueMap[string(*entity)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -44,17 +47,22 @@ func (m *EnumTypeConverter[DTO, MODEL]) ToDto(model *MODEL) *DTO {
|
|||||||
return &dto
|
return &dto
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *EnumTypeConverter[DTO, MODEL]) NewConverterPair() []copier.TypeConverter {
|
func (m *EnumTypeConverter[DTO, ENTITY]) NewConverterPair() []copier.TypeConverter {
|
||||||
srcType := MODEL("")
|
srcType := ENTITY("")
|
||||||
dstType := DTO(0)
|
dstType := DTO(0)
|
||||||
|
|
||||||
fromFn := m.ToDto
|
fromFn := m.ToDTO
|
||||||
toFn := m.ToModel
|
toFn := m.ToEntity
|
||||||
|
|
||||||
return NewGenericTypeConverterPair(&srcType, &dstType, fromFn, toFn)
|
return NewGenericTypeConverterPair(&srcType, &dstType, fromFn, toFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGenericTypeConverterPair[A interface{}, B interface{}](srcType A, dstType B, fromFn func(src A) B, toFn func(src B) A) []copier.TypeConverter {
|
func NewGenericTypeConverterPair[A interface{}, B interface{}](
|
||||||
|
srcType A,
|
||||||
|
dstType B,
|
||||||
|
fromFn func(src A) B,
|
||||||
|
toFn func(src B) A,
|
||||||
|
) []copier.TypeConverter {
|
||||||
return []copier.TypeConverter{
|
return []copier.TypeConverter{
|
||||||
{
|
{
|
||||||
SrcType: srcType,
|
SrcType: srcType,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package mapper
|
package mapper
|
||||||
|
|
||||||
// Mapper defines the interface for converting between DTOs and models.
|
// Mapper defines the interface for converting between Data Transfer Objects (DTOs) and Database Entities.
|
||||||
type Mapper[DTO any, MODEL any] interface {
|
type Mapper[DTO any, ENTITY any] interface {
|
||||||
// ToModel converts a DTO to a MODEL.
|
// ToEntity converts a DTO to a Database Entity.
|
||||||
ToModel(*DTO) *MODEL
|
ToEntity(*DTO) *ENTITY
|
||||||
|
|
||||||
// ToDto converts a MODEL to a DTO.
|
// ToDTO converts a Database Entity to a DTO.
|
||||||
ToDto(*MODEL) *DTO
|
ToDTO(*ENTITY) *DTO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,46 +4,46 @@ import (
|
|||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CopierMapper[DTO any, MODEL any] struct {
|
type CopierMapper[DTO any, ENTITY any] struct {
|
||||||
copierOption copier.Option
|
copierOption copier.Option
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCopierMapper[DTO any, MODEL any]() *CopierMapper[DTO, MODEL] {
|
func NewCopierMapper[DTO any, ENTITY any]() *CopierMapper[DTO, ENTITY] {
|
||||||
return &CopierMapper[DTO, MODEL]{
|
return &CopierMapper[DTO, ENTITY]{
|
||||||
copierOption: copier.Option{
|
copierOption: copier.Option{
|
||||||
Converters: []copier.TypeConverter{},
|
Converters: []copier.TypeConverter{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CopierMapper[DTO, MODEL]) AppendConverter(converter copier.TypeConverter) {
|
func (m *CopierMapper[DTO, ENTITY]) AppendConverter(converter copier.TypeConverter) {
|
||||||
m.copierOption.Converters = append(m.copierOption.Converters, converter)
|
m.copierOption.Converters = append(m.copierOption.Converters, converter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CopierMapper[DTO, MODEL]) AppendConverters(converters []copier.TypeConverter) {
|
func (m *CopierMapper[DTO, ENTITY]) AppendConverters(converters []copier.TypeConverter) {
|
||||||
m.copierOption.Converters = append(m.copierOption.Converters, converters...)
|
m.copierOption.Converters = append(m.copierOption.Converters, converters...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CopierMapper[DTO, MODEL]) ToModel(dto *DTO) *MODEL {
|
func (m *CopierMapper[DTO, ENTITY]) ToEntity(dto *DTO) *ENTITY {
|
||||||
if dto == nil {
|
if dto == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var model MODEL
|
var entity ENTITY
|
||||||
if err := copier.CopyWithOption(&model, dto, m.copierOption); err != nil {
|
if err := copier.CopyWithOption(&entity, dto, m.copierOption); err != nil {
|
||||||
panic(err) // Handle error appropriately in production code
|
panic(err) // Handle error appropriately in production code
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model
|
return &entity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CopierMapper[DTO, MODEL]) ToDto(model *MODEL) *DTO {
|
func (m *CopierMapper[DTO, ENTITY]) ToDTO(entity *ENTITY) *DTO {
|
||||||
if model == nil {
|
if entity == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var dto DTO
|
var dto DTO
|
||||||
if err := copier.CopyWithOption(&dto, model, m.copierOption); err != nil {
|
if err := copier.CopyWithOption(&dto, entity, m.copierOption); err != nil {
|
||||||
panic(err) // Handle error appropriately in production code
|
panic(err) // Handle error appropriately in production code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,39 +12,39 @@ func TestCopierMapper(t *testing.T) {
|
|||||||
Age int
|
Age int
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModelType struct {
|
type EntityType struct {
|
||||||
Name string
|
Name string
|
||||||
Age int
|
Age int
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper := NewCopierMapper[DtoType, ModelType]()
|
mapper := NewCopierMapper[DtoType, EntityType]()
|
||||||
|
|
||||||
// 测试 ToModel 方法
|
// 测试 ToEntity 方法
|
||||||
dto := &DtoType{Name: "Alice", Age: 25}
|
dto := &DtoType{Name: "Alice", Age: 25}
|
||||||
model := mapper.ToModel(dto)
|
entity := mapper.ToEntity(dto)
|
||||||
assert.NotNil(t, model)
|
assert.NotNil(t, entity)
|
||||||
assert.Equal(t, "Alice", model.Name)
|
assert.Equal(t, "Alice", entity.Name)
|
||||||
assert.Equal(t, 25, model.Age)
|
assert.Equal(t, 25, entity.Age)
|
||||||
|
|
||||||
// 测试 ToModel 方法,传入 nil
|
// 测试 ToEntity 方法,传入 nil
|
||||||
modelNil := mapper.ToModel(nil)
|
entityNil := mapper.ToEntity(nil)
|
||||||
assert.Nil(t, modelNil)
|
assert.Nil(t, entityNil)
|
||||||
|
|
||||||
// 测试 ToDto 方法
|
// 测试 ToDTO 方法
|
||||||
model = &ModelType{Name: "Bob", Age: 30}
|
entity = &EntityType{Name: "Bob", Age: 30}
|
||||||
dtoResult := mapper.ToDto(model)
|
dtoResult := mapper.ToDTO(entity)
|
||||||
assert.NotNil(t, dtoResult)
|
assert.NotNil(t, dtoResult)
|
||||||
assert.Equal(t, "Bob", dtoResult.Name)
|
assert.Equal(t, "Bob", dtoResult.Name)
|
||||||
assert.Equal(t, 30, dtoResult.Age)
|
assert.Equal(t, 30, dtoResult.Age)
|
||||||
|
|
||||||
// 测试 ToDto 方法,传入 nil
|
// 测试 ToDTO 方法,传入 nil
|
||||||
dtoNil := mapper.ToDto(nil)
|
dtoNil := mapper.ToDTO(nil)
|
||||||
assert.Nil(t, dtoNil)
|
assert.Nil(t, dtoNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnumTypeConverter(t *testing.T) {
|
func TestEnumTypeConverter(t *testing.T) {
|
||||||
type DtoType int32
|
type DtoType int32
|
||||||
type ModelType string
|
type EntityType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DtoTypeOne DtoType = 1
|
DtoTypeOne DtoType = 1
|
||||||
@@ -52,8 +52,8 @@ func TestEnumTypeConverter(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ModelTypeOne ModelType = "One"
|
EntityTypeOne EntityType = "One"
|
||||||
ModelTypeTwo ModelType = "Two"
|
EntityTypeTwo EntityType = "Two"
|
||||||
)
|
)
|
||||||
|
|
||||||
nameMap := map[int32]string{
|
nameMap := map[int32]string{
|
||||||
@@ -65,29 +65,29 @@ func TestEnumTypeConverter(t *testing.T) {
|
|||||||
"Two": 2,
|
"Two": 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
converter := NewEnumTypeConverter[DtoType, ModelType](nameMap, valueMap)
|
converter := NewEnumTypeConverter[DtoType, EntityType](nameMap, valueMap)
|
||||||
|
|
||||||
// 测试 ToModel 方法
|
// 测试 ToEntity 方法
|
||||||
dto := DtoTypeOne
|
dto := DtoTypeOne
|
||||||
model := converter.ToModel(&dto)
|
entity := converter.ToEntity(&dto)
|
||||||
assert.NotNil(t, model)
|
assert.NotNil(t, entity)
|
||||||
assert.Equal(t, "One", string(*model))
|
assert.Equal(t, "One", string(*entity))
|
||||||
|
|
||||||
// 测试 ToModel 方法,传入不存在的值
|
// 测试 ToEntity 方法,传入不存在的值
|
||||||
dtoInvalid := DtoType(3)
|
dtoInvalid := DtoType(3)
|
||||||
modelInvalid := converter.ToModel(&dtoInvalid)
|
entityInvalid := converter.ToEntity(&dtoInvalid)
|
||||||
assert.Nil(t, modelInvalid)
|
assert.Nil(t, entityInvalid)
|
||||||
|
|
||||||
// 测试 ToDto 方法
|
// 测试 ToDTO 方法
|
||||||
tmpModelTwo := ModelTypeTwo
|
tmpEntityTwo := EntityTypeTwo
|
||||||
model = &tmpModelTwo
|
entity = &tmpEntityTwo
|
||||||
dtoResult := converter.ToDto(model)
|
dtoResult := converter.ToDTO(entity)
|
||||||
assert.NotNil(t, dtoResult)
|
assert.NotNil(t, dtoResult)
|
||||||
assert.Equal(t, DtoType(2), *dtoResult)
|
assert.Equal(t, DtoType(2), *dtoResult)
|
||||||
|
|
||||||
// 测试 ToDto 方法,传入不存在的值
|
// 测试 ToDTO 方法,传入不存在的值
|
||||||
tmpModelThree := ModelType("Three")
|
tmpEntityThree := EntityType("Three")
|
||||||
modelInvalid = &tmpModelThree
|
entityInvalid = &tmpEntityThree
|
||||||
dtoInvalidResult := converter.ToDto(modelInvalid)
|
dtoInvalidResult := converter.ToDTO(entityInvalid)
|
||||||
assert.Nil(t, dtoInvalidResult)
|
assert.Nil(t, dtoInvalidResult)
|
||||||
}
|
}
|
||||||
|
|||||||
2
tag.bat
2
tag.bat
@@ -8,7 +8,7 @@ git tag jwtutil/v0.0.2
|
|||||||
git tag id/v0.0.2
|
git tag id/v0.0.2
|
||||||
git tag slug/v0.0.1
|
git tag slug/v0.0.1
|
||||||
git tag name_generator/v0.0.1
|
git tag name_generator/v0.0.1
|
||||||
git tag mapper/v0.0.2
|
git tag mapper/v0.0.3
|
||||||
git tag password/v0.0.1
|
git tag password/v0.0.1
|
||||||
|
|
||||||
git tag entgo/v1.1.31
|
git tag entgo/v1.1.31
|
||||||
|
|||||||
Reference in New Issue
Block a user