Setting: extend
extend [PACKAGE:]FUNC...
can be defined as CLI argument or conversion comment.
If a type cannot be converted automatically, you can manually define an implementation with :extend
for the missing mapping. Keep in mind, Goverter will use the custom implementation every time, when the source and target type matches.
The FUNC
may have the signatures described in Signature: Optional Source.
You can optionally define the PACKAGE
where FUNC
is located by separating the PACKAGE
and FUNC
with a :
(colon). If no package is defined, then the package of the conversion method is used.
TYPE
can be a regex if you want to include multiple methods from the same package. E.g. extend IntTo.*
.
Here are some examples using extend
.
Simple (click to expand)
go
package example
import "fmt"
// goverter:converter
// goverter:extend IntToString
type Converter interface {
Convert(Input) Output
}
type Input struct {
Name string
Age int
}
type Output struct {
Name string
Age string
}
func IntToString(i int) string {
return fmt.Sprint(i)
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import extendlocal "github.com/jmattheis/goverter/example/extend-local"
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source extendlocal.Input) extendlocal.Output {
var exampleOutput extendlocal.Output
exampleOutput.Name = source.Name
exampleOutput.Age = extendlocal.IntToString(source.Age)
return exampleOutput
}
Complex (click to expand)
go
package example
// goverter:converter
// goverter:extend ExtractFriendNames
type Converter interface {
Convert(source []InputPerson) []OutputPerson
}
type InputPerson struct {
Name string
Friends []InputPerson
}
type OutputPerson struct {
Name string
Friends []string
}
func ExtractFriendNames(persons []InputPerson) []string {
var names []string
for _, person := range persons {
names = append(names, person.Name)
}
return names
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import extendlocalcomplex "github.com/jmattheis/goverter/example/extend-local-complex"
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source []extendlocalcomplex.InputPerson) []extendlocalcomplex.OutputPerson {
var exampleOutputPersonList []extendlocalcomplex.OutputPerson
if source != nil {
exampleOutputPersonList = make([]extendlocalcomplex.OutputPerson, len(source))
for i := 0; i < len(source); i++ {
exampleOutputPersonList[i] = c.exampleInputPersonToExampleOutputPerson(source[i])
}
}
return exampleOutputPersonList
}
func (c *ConverterImpl) exampleInputPersonToExampleOutputPerson(source extendlocalcomplex.InputPerson) extendlocalcomplex.OutputPerson {
var exampleOutputPerson extendlocalcomplex.OutputPerson
exampleOutputPerson.Name = source.Name
exampleOutputPerson.Friends = extendlocalcomplex.ExtractFriendNames(source.Friends)
return exampleOutputPerson
}
With PACKAGE
(click to expand)
go
package example
// goverter:converter
// goverter:extend strconv:Atoi
type Converter interface {
Convert(Input) (Output, error)
}
type Input struct{ Value string }
type Output struct{ Value int }
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import (
extendexternal "github.com/jmattheis/goverter/example/extend-external"
"strconv"
)
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source extendexternal.Input) (extendexternal.Output, error) {
var exampleOutput extendexternal.Output
xint, err := strconv.Atoi(source.Value)
if err != nil {
return exampleOutput, err
}
exampleOutput.Value = xint
return exampleOutput, nil
}
With Conversion interface (click to expand)
go
package example
// goverter:converter
// goverter:extend ConvertAnimals
type Converter interface {
Convert(source Input) Output
// used only in extend method
ConvertDogs([]Dog) []Animal
ConvertCats([]Cat) []Animal
}
type Input struct {
Animals InputAnimals
}
type InputAnimals struct {
Cats []Cat
Dogs []Dog
}
type Output struct {
Animals []Animal
}
type Cat struct{ Name string }
type Dog struct{ Name string }
type Animal struct{ Name string }
func ConvertAnimals(c Converter, input InputAnimals) []Animal {
dogs := c.ConvertDogs(input.Dogs)
cats := c.ConvertCats(input.Cats)
return append(dogs, cats...)
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import extendlocalwithconverter "github.com/jmattheis/goverter/example/extend-local-with-converter"
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source extendlocalwithconverter.Input) extendlocalwithconverter.Output {
var exampleOutput extendlocalwithconverter.Output
exampleOutput.Animals = extendlocalwithconverter.ConvertAnimals(c, source.Animals)
return exampleOutput
}
func (c *ConverterImpl) ConvertCats(source []extendlocalwithconverter.Cat) []extendlocalwithconverter.Animal {
var exampleAnimalList []extendlocalwithconverter.Animal
if source != nil {
exampleAnimalList = make([]extendlocalwithconverter.Animal, len(source))
for i := 0; i < len(source); i++ {
exampleAnimalList[i] = c.exampleCatToExampleAnimal(source[i])
}
}
return exampleAnimalList
}
func (c *ConverterImpl) ConvertDogs(source []extendlocalwithconverter.Dog) []extendlocalwithconverter.Animal {
var exampleAnimalList []extendlocalwithconverter.Animal
if source != nil {
exampleAnimalList = make([]extendlocalwithconverter.Animal, len(source))
for i := 0; i < len(source); i++ {
exampleAnimalList[i] = c.exampleDogToExampleAnimal(source[i])
}
}
return exampleAnimalList
}
func (c *ConverterImpl) exampleCatToExampleAnimal(source extendlocalwithconverter.Cat) extendlocalwithconverter.Animal {
var exampleAnimal extendlocalwithconverter.Animal
exampleAnimal.Name = source.Name
return exampleAnimal
}
func (c *ConverterImpl) exampleDogToExampleAnimal(source extendlocalwithconverter.Dog) extendlocalwithconverter.Animal {
var exampleAnimal extendlocalwithconverter.Animal
exampleAnimal.Name = source.Name
return exampleAnimal
}
With context (click to expand)
go
package example
import "time"
// goverter:converter
// goverter:extend FormatTime
type Converter interface {
Convert(source map[string]Input, ctxFormat string) map[string]Output
}
func FormatTime(t time.Time, ctxFormat string) string {
return t.Format(ctxFormat)
}
type Input struct {
Name string
CreatedAt time.Time
}
type Output struct {
Name string
CreatedAt string
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import dateformat "github.com/jmattheis/goverter/example/context/date-format"
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source map[string]dateformat.Input, context string) map[string]dateformat.Output {
var mapStringExampleOutput map[string]dateformat.Output
if source != nil {
mapStringExampleOutput = make(map[string]dateformat.Output, len(source))
for key, value := range source {
mapStringExampleOutput[key] = c.exampleInputToExampleOutput(value, context)
}
}
return mapStringExampleOutput
}
func (c *ConverterImpl) exampleInputToExampleOutput(source dateformat.Input, context string) dateformat.Output {
var exampleOutput dateformat.Output
exampleOutput.Name = source.Name
exampleOutput.CreatedAt = dateformat.FormatTime(source.CreatedAt, context)
return exampleOutput
}
With error (click to expand)
go
package example
import "strconv"
// goverter:converter
// goverter:extend StringToInt
type Converter interface {
Convert(Input) (Output, error)
}
type Input struct{ Value string }
type Output struct{ Value int }
func StringToInt(value string) (int, error) {
i, err := strconv.Atoi(value)
return i, err
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package generated
import extendwitherror "github.com/jmattheis/goverter/example/extend-with-error"
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source extendwitherror.Input) (extendwitherror.Output, error) {
var exampleOutput extendwitherror.Output
xint, err := extendwitherror.StringToInt(source.Value)
if err != nil {
return exampleOutput, err
}
exampleOutput.Value = xint
return exampleOutput, nil
}