automapper

package module
v0.0.0-...-a500e58 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2020 License: MIT Imports: 3 Imported by: 0

README

Automapper for Golang

Introduction

The Automapper is the package for Go programs mapping values in different structs

The import path for the package is github.com/gnoah1379/automapper
To install it, run:

go get github.com/gnoah1379/automapper

Features

  • Support mapping struct-to-struct
  • Support mapping slice/array-to-slice/array
  • Support Custom transform values
  • Support Nested mapping (including slice/array)

Mapper

Mapper is an interface

type Mapper interface {
	Type() string
	Mapping(src, dst interface{}) error
	MakeDestination(src reflect.Value) interface{}
	Transform(identifier string, handler TransformHandler) Mapper
	Ignore(identifier string) Mapper
	Condition(identifier string, conditionHandler ConditionHandler) Mapper
	Nested(identifier, target string, mapper Mapper) Mapper
}
  • Template return the template of the mapper
  • Mapping mapping object-object(the parameters need is a pointer), slice-slice, array-array
  • MakeDestination like the Mapping method, but the destination object will be created inside this method
  • Transform is the method define a custom transform for dst fields
  • Ignore ignore mapping a field
  • Condition execute FromField with default identifier if condition is true
  • Nested execute Mapping from target field to identifier field via the parameter mapper
NameMapper
func NewNameMapper(template Template, profile map[string]string) (*NameMapper, error) 
func (nm *NameMapper) SetProfile(profile map[string]string) error 

NameMapper is the implement of the Mapper interface.
Make a mapper via the profile, and the public fields' names.
The profile is a map[string]string with keys are the names of the destination fields and values are the names of source fields are mapped together.
The parameter identifier is the public name of the field.
Default, the fields of the destination object will be mapping with fields of the source object via values defined in the profile.
It panicif the types of the source's fields different from the types of the destination fields.

Template

func NewTemplate(src, dst interface{}) Template
func (t Template) ProfileSameTag() map[string]string
func (t Template) ProfileSameName() map[string]string 
  • NewTemplate the method creates a Template. The src and dst parameters are template instances of structs; It can be an empty struct.
  • ProfileSameName make a profile with the fields had the same name will be mapped to each other.
  • ProfileSameTag make a profile with the fields had the same tag will be mapped to each other.

TransformHandler

type TransformHandler func(SrcMap FieldMap) interface{}

TransformHandler is a callback with input is FieldMap of the source object, and returns a field of the destination object.

func FromField(srcFieldName string) TransformHandler

This is the default handler. Will be returned to the target value.

FieldMap

func (fm FieldMap) Mapping(SrcMap FieldMap, transformers map[string]TransformHandler) 
func (fm FieldMap) Field(identifier string) reflect.Value
func (f FieldMap)  String(fieldName string) string 
func (f FieldMap)  Int64(identifier string) int64
func (f FieldMap)  Int(fieldName string) int
func (f FieldMap)  Float(fieldName string) float64
func (f FieldMap)  Complex(identifier string) complex128
func (f FieldMap)  Bytes(fieldName string) []byte
func (f FieldMap)  Bool(fieldName string) bool
func (f FieldMap)  Interface(fieldName string) interface{}

FieldMap is the map of reflect.Value with a key is the field name. You can call the Field(fieldName string) method or other methods to get the value of the field corresponding.
You can't call the Set method to set the value for a variable you get from FieldMap, it not references to the source object, any attempt to change it will cause panic; This is to make sure the source object will not be changed after mapping.
The Mapping method will be mapping values from SrcMap to DstMap via the transform handlers corresponding.

Util

func IGNORE() interface{} 

In the Transform methods, return the result of the IGNORE() method to ignore mapping the current field.

Example

package main

import (
	"automapper"
	"fmt"
)

type PersonUser struct {
	Username string `automapper:"user"`
}
type EmployeeUser struct {
	User string `automapper:"user"`
}

type Person struct {
	FirstName string       `automapper:"firstName"`
	LastName  string       `automapper:"lastName"`
	Age       int          `automapper:"age"`
	User      []PersonUser `automapper:"user"`
}

type Employee struct {
	FullName  string         `automapper:"fullName"`
	Age       int            `automapper:"age"`
	FirstName string         `automapper:"firstName"`
	LastName  string         `automapper:"lastName"`
	User      []EmployeeUser `automapper:"user"`
}

func main() {
	var err error
	//create test data
	LPerson := make([]Person, 2)
	LEmployee := make([]Employee, 2)
	OEmployee := Employee{}
	OPerson := Person{
		FirstName: "Hoang",
		LastName:  "Nguyen Hai",
		Age:       23,
		User: []PersonUser{
			{Username: "hoangnh01"},
			{Username: "hoangnh02"}},
	}
	LPerson[0] = Person{
		Age:       27,
		FirstName: "Thuoc",
		LastName:  "Nguyen Van",
		User: []PersonUser{
			{Username: "thuocnv01"},
			{Username: "thuocnv02"},
		},
	}
	LPerson[1] = Person{
		Age:       17,
		FirstName: "Quang Hung",
		LastName:  "Tran",
		User: []PersonUser{
			{Username: "hungqt01"},
			{Username: "hungqt02"},
		},
	}

	// new template and profile
	template := automapper.NewTemplate(Person{}, Employee{})
	userTemplate := automapper.NewTemplate(PersonUser{}, EmployeeUser{})

	// new mapper via tag
	mapper,err := automapper.NewNameMapper(template,template.ProfileSameTag())
	if err != nil{
		panic(err)
	}
	userMapper,err := automapper.NewNameMapper(userTemplate, userTemplate.ProfileSameName())
	if err != nil{
		panic(err)
	}
	mapper.Transform(
		"FullName", func(SrcMap automapper.FieldMap) interface{} {
			return SrcMap.String("FirstName") + " " + SrcMap.String("LastName")

		},
	).Ignore("LastName",
	).Condition("Age", func(SrcMap automapper.FieldMap) bool {
		return SrcMap.Int("Age") > 18

	}).Nested("User", "User", userMapper)

	// test via tag
	fmt.Println("______ViaTag_______")
	fmt.Println("______Struct_______")
	err = mapper.Mapping(&OPerson, &OEmployee)
	if err != nil {
		panic(err)
	}
	fmt.Println("Persons  :", OPerson)
	fmt.Println("Employees:", OEmployee)
	fmt.Println("______Slice_______")
	err = mapper.Mapping(LPerson, LEmployee)
	if err != nil {
		panic(err)
	}
	fmt.Println("ListPersons  :", LPerson)
	fmt.Println("ListEmployees:", LEmployee)

	// reset
	LEmployee = make([]Employee, 2)
	OEmployee = Employee{}

	// new mapper via profile
	mapper,err = automapper.NewNameMapper(template, template.ProfileSameName())
	if err != nil{
		panic(err)
	}
	userMapper,err = automapper.NewNameMapper(userTemplate, userTemplate.ProfileSameTag())
	if err != nil{
		panic(err)
	}
	mapper.Transform(
		"FullName", func(SrcMap automapper.FieldMap) interface{} {
			return SrcMap.String("FirstName") + " " + SrcMap.String("LastName")

		},
	).Ignore("LastName",
	).Condition("Age", func(SrcMap automapper.FieldMap) bool {
		return SrcMap.Int("Age") > 18

	}).Nested("User", "User", userMapper)

	// test via profile
	fmt.Println("______ViaProfile_______")
	fmt.Println("______Struct_______")
	err = mapper.Mapping(&OPerson, &OEmployee)
	if err != nil {
		panic(err)
	}
	fmt.Println("Persons  :", OPerson)
	fmt.Println("Employees:", OEmployee)
	fmt.Println("______Slice_______")
	err = mapper.Mapping(LPerson, LEmployee)
	if err != nil {
		panic(err)
	}
	fmt.Println("ListPersons  :", LPerson)
	fmt.Println("ListEmployees:", LEmployee)
}

Documentation

Index

Constants

View Source
const TAG = "automapper"

Variables

This section is empty.

Functions

func IGNORE

func IGNORE() interface{}

func NewFieldMapViaTemplate

func NewFieldMapViaTemplate(src, dst reflect.Value, t Template) (SrcMap FieldMap, DstMap FieldMap)

Types

type Condition

type Condition interface {
	Condition(identifier string, conditionHandler ConditionHandler) Mapper
}

type ConditionHandler

type ConditionHandler func(SrcMap FieldMap) bool

type Error

type Error string
const (
	DoesNotExist       Error = "does not exist or is non-public field"
	IdentifierNotFound Error = "identifier not found"
	IsNilOrInvalid     Error = "is nil or invalid"
	IsDifferentType    Error = "is different type"
	InvalidMapper      Error = "invalid mapper"
	InvalidParameter   Error = "invalid parameter"
	UndefinedError     Error = "undefined error"
)

func (Error) Error

func (e Error) Error() string

type FieldMap

type FieldMap struct {
	// contains filtered or unexported fields
}

func (FieldMap) Bool

func (fm FieldMap) Bool(identifier string) bool

func (FieldMap) Bytes

func (fm FieldMap) Bytes(identifier string) []byte

func (FieldMap) Complex

func (fm FieldMap) Complex(identifier string) complex128

func (FieldMap) Field

func (fm FieldMap) Field(identifier string) reflect.Value

func (FieldMap) Float

func (fm FieldMap) Float(identifier string) float64

func (FieldMap) Int

func (fm FieldMap) Int(identifier string) int

func (FieldMap) Int64

func (fm FieldMap) Int64(identifier string) int64

func (FieldMap) Interface

func (fm FieldMap) Interface(identifier string) interface{}

func (FieldMap) Mapping

func (fm FieldMap) Mapping(SrcMap FieldMap, transformers map[string]TransformHandler)

func (FieldMap) String

func (fm FieldMap) String(identifier string) string

type GetTemplate

type GetTemplate interface {
	Template() Template
}

type Ignore

type Ignore interface {
	Ignore(identifier string) Mapper
}

type MakeDestination

type MakeDestination interface {
	MakeDestination(src interface{}) (interface{}, error)
}

type Mapping

type Mapping interface {
	Mapping(src, dst interface{}) error
}

type NameMapper

type NameMapper struct {
	// contains filtered or unexported fields
}

func NewNameMapper

func NewNameMapper(template Template, profile map[string]string) (*NameMapper, error)

func (*NameMapper) Condition

func (nm *NameMapper) Condition(name string, conditionHandler ConditionHandler) Mapper

func (*NameMapper) Ignore

func (nm *NameMapper) Ignore(name string) Mapper

func (*NameMapper) MakeDestination

func (nm *NameMapper) MakeDestination(source interface{}) (interface{}, error)

func (*NameMapper) Mapping

func (nm *NameMapper) Mapping(src interface{}, dst interface{}) (err error)

func (*NameMapper) Nested

func (nm *NameMapper) Nested(name, target string, mapper Mapper) Mapper

func (*NameMapper) SetProfile

func (nm *NameMapper) SetProfile(profile map[string]string) error

func (*NameMapper) Template

func (nm *NameMapper) Template() Template

func (*NameMapper) Transform

func (nm *NameMapper) Transform(name string, handler TransformHandler) Mapper

type Nested

type Nested interface {
	Nested(name, target string, mapper Mapper) Mapper
}

type Template

type Template struct {
	// contains filtered or unexported fields
}

func NewTemplate

func NewTemplate(src, dst interface{}) Template

func (Template) ProfileSameName

func (t Template) ProfileSameName() map[string]string

func (Template) ProfileSameTag

func (t Template) ProfileSameTag() map[string]string

type Transform

type Transform interface {
	Transform(identifier string, handler TransformHandler) Mapper
}

type TransformHandler

type TransformHandler func(SrcMap FieldMap) interface{}

func FromField

func FromField(target string) TransformHandler

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL