Skip to content

Latest commit

 

History

History
232 lines (187 loc) · 4.96 KB

README.zh_cn.md

File metadata and controls

232 lines (187 loc) · 4.96 KB

go-conv

Build Status Go Report Card

根据函数类型声明自动生成转换代码,支持转换/深拷贝模式,支持应用扩展自定义转换函数/过滤/忽略特定字段等选项

Feature

  • 支持conv/deepCopy模式
  • 支持范型
  • 支持自动解指针
  • 支持基础类型/map/slice/array/struct 转换
  • 支持基础类型自动向上转型
  • 支持Alias类型自动转换
  • 支持embed field自动解包
  • 支持自引用对象,支持递归转换
  • 自动处理同名包冲突
  • 支持string <-> []byte/[]rune 互转
  • 支持Pointer <-> Struct 互转
  • 支持Array <-> Slice 互转
  • 支持扩展自定义转换/过滤/忽略选项

Example

生成命令:

go run github.com/ycl2018/go-conv@latest ./...

conv模式

conv模式是默认使用的类型转换模式,采用浅拷贝,提高转换性能

// go-conv:generate
var Foo2Bar func (src *Foo) *Bar

type Foo struct {
    Str     string
    Slice   []string
    Map     map[string]string
    Pointer string
    Alias   string
}

type Bar struct {
    Str     string
    Slice   []string
    Map     map[string]string
    Pointer *string
    Alias   StringAlias
}

type StringAlias string

generated:

// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.

package testdata

func FooToBar(src *Foo) (dst *Bar) {
	if src != nil {
		dst = new(Bar)
		dst.Str = src.Str
		dst.Slice = src.Slice
		dst.Map = src.Map
		dst.Pointer = &src.Pointer
		dst.Alias = (StringAlias)(src.Alias)
	}
	return
}
func init() {
	Foo2Bar = FooToBar
}

copy模式

copy模式使用深拷贝模式拷贝结构体的每个字段

// go-conv:generate
// go-conv:copy
var Foo2Bar func(src *Foo) *Bar

type Foo struct {
	Str     string
	Slice   []string
	Map     map[string]string
	Pointer string
	Alias   string
}

type Bar struct {
	Str     string
	Slice   []string
	Map     map[string]string
	Pointer *string
	Alias   StringAlias
}

type StringAlias string

generated:

// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.

package example

func CopyPtrFooToPtrBar(src *Foo) (dst *Bar) {
	if src != nil {
		dst = new(Bar)
		dst.Str = src.Str
		if len(src.Slice) > 0 {
			dst.Slice = make([]string, len(src.Slice))
			for i := 0; i < len(src.Slice); i++ {
				dst.Slice[i] = src.Slice[i]
			}
		}
		if len(src.Map) > 0 {
			dst.Map = make(map[string]string, len(src.Map))
			for k, v := range src.Map {
				var tmpK string
				var tmpV string
				tmpK = k
				tmpV = v
				dst.Map[tmpK] = tmpV
			}
		}
		dst.Pointer = new(string)
		*dst.Pointer = src.Pointer
		dst.Alias = StringAlias(src.Alias)
	}
	return
}
func init() {
	Foo2Bar = CopyPtrFooToPtrBar
}

扩展选项

可使用go-conv:apply 指定要应用的配置,编程式ide友好,配置更方便

package cases

import (
	"strconv"

	"github.com/ycl2018/go-conv/option"
	"github.com/ycl2018/go-conv/testdata/a"
	"github.com/ycl2018/go-conv/testdata/b"
)

// Struct2Struct conv a Basic to b Basic
// go-conv:generate
// go-conv:apply basicConvOpts
var Struct2Struct func(p *a.Struct) *b.Struct


var basicConvOpts = []option.Option{
	option.WithIgnoreFields(a.Struct{}, []string{"Pojo"}),
	option.WithIgnoreTypes(a.Student{}, "Student3"),
	option.WithTransformer(transfer, "Student2.Class.Grade"),
	option.WithFilter(filter, "Student2.Teachers"),
	option.WithFieldMatch(a.Struct{}, map[string]string{
		"Match": "Match_",
	}),
	option.WithMatchCaseInsensitive(),
	option.WithNoInitFunc(),
}

func transfer(t int) string {
	return strconv.Itoa(t)
}

func filter(arr []string) []string {
	return arr
}
// Code generated by github.com/ycl2018/go-conv DO NOT EDIT.

package cases

import (
	"github.com/ycl2018/go-conv/testdata/a"
	"github.com/ycl2018/go-conv/testdata/b"
)

func PtrAStructToPtrBStruct(src *a.Struct) (dst *b.Struct) {
	if src != nil {
		dst = new(b.Struct)
		dst.Student.Name = src.Student.Name
		dst.Student.Class.Name = src.Student.Class.Name
		dst.Student.Class.Grade = string(src.Student.Class.Grade)
		dst.Student.Teachers = src.Student.Teachers
		dst.Student2.Name = src.Student2.Name
		dst.Student2.Class.Name = src.Student2.Class.Name
		// apply transfer option on transfer
		transferredSrcStudent2ClassGrade := transfer(src.Student2.Class.Grade)
		dst.Student2.Class.Grade = transferredSrcStudent2ClassGrade
		// apply filter option on filter
		filteredSrcStudent2Teachers := filter(src.Student2.Teachers)
		dst.Student2.Teachers = filteredSrcStudent2Teachers
		// apply ignore option on src.Student3
		// apply ignore option on src.Pojo
		dst.Match_ = src.Match
		dst.Caseinsensitive = src.CaseInsensitive
	}
	return
}

更多使用实例请参考 testdata 目录