Skip to content

How to convert embedded structs ‚Äč

Goverter sees embedded structs like any other field. This means you can access them via the type name in ignore or map.

Given this model.

go
package example

type Person struct {
	Address
	Name string
}
type Address struct {
	Street  string
	ZipCode string
}
type FlatPerson struct {
	Name       string
	StreetName string
	ZipCode    string
}

Notice the embedded struct Address on Person.

When defining the conversion method for Person (containing the embedded struct) to FlatPerson, you have to manually define the mapping for Address like this:

go
package example

// goverter:converter
// goverter:output:file generated/fromembedded.go
type FromConverter interface {
	// goverter:map Address.ZipCode ZipCode
	// goverter:map Address.Street StreetName
	FromEmbedded(Person) FlatPerson
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import embedded "github.com/jmattheis/goverter/example/embedded"

type FromConverterImpl struct{}

func (c *FromConverterImpl) FromEmbedded(source embedded.Person) embedded.FlatPerson {
	var exampleFlatPerson embedded.FlatPerson
	exampleFlatPerson.Name = source.Name
	exampleFlatPerson.StreetName = source.Address.Street
	exampleFlatPerson.ZipCode = source.Address.ZipCode
	return exampleFlatPerson
}

In some cases it's useful to use autoMap if the embedded struct has equally named fields.


For the reverse operation you actually have to define two methods because of the rules defined in Guide: Configure Nested. For the given example it would look like this:

go
package example

// goverter:converter
// goverter:output:file generated/toembedded.go
type ToConverter interface {
	// goverter:map . Address
	ToEmbedded(FlatPerson) Person

	// goverter:map StreetName Street
	ToEmbeddedAddress(FlatPerson) Address
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import embedded "github.com/jmattheis/goverter/example/embedded"

type ToConverterImpl struct{}

func (c *ToConverterImpl) ToEmbedded(source embedded.FlatPerson) embedded.Person {
	var examplePerson embedded.Person
	examplePerson.Address = c.ToEmbeddedAddress(source)
	examplePerson.Name = source.Name
	return examplePerson
}
func (c *ToConverterImpl) ToEmbeddedAddress(source embedded.FlatPerson) embedded.Address {
	var exampleAddress embedded.Address
	exampleAddress.Street = source.StreetName
	exampleAddress.ZipCode = source.ZipCode
	return exampleAddress
}