Skip to content

Setting: output

output:file

output:file FILE can be defined as CLI argument or conversion comment. Default is ./generated/generated.go.

output:file sets the generated output file of a converter interface. The file location is relative to the file with the converter interface. E.g. if the interface is located at /home/jm/src/pkg/converter/interface.go and you define output:file ../generated/output.go then the file would be created at /home/jm/src/pkg/generated/interface.go

You can use the magic @cwd/ prefix to reference the current working directory goverter is executed in. E.g. you execute goverter in /home/jm/src/pkg/, the interface is located at /home/jm/src/pkg/converter/interface.go and output:file @cwd/output/generated.go is defined then the file would be created at /home/jm/src/pkg/output/generated.go.

Different converters may have the same output:file if the output:package is the same. See this more complex example:

go
package example

// goverter:converter
// goverter:output:file ./a/generated.go
// goverter:output:package goverter/example/a
type RootA interface {
	Convert([]bool) []bool
}

// goverter:converter
// goverter:output:file ./b/generated.go
// goverter:output:package goverter/example/b
type RootB interface {
	Convert([]string) []string
}
go
package c

// goverter:converter
// goverter:output:file ../a/generated.go
// goverter:output:package goverter/example/a
type CIntoA interface {
	Convert([]int) []int
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package a

type CIntoAImpl struct{}

func (c *CIntoAImpl) Convert(source []int) []int {
	var intList []int
	if source != nil {
		intList = make([]int, len(source))
		for i := 0; i < len(source); i++ {
			intList[i] = source[i]
		}
	}
	return intList
}

type RootAImpl struct{}

func (c *RootAImpl) Convert(source []bool) []bool {
	var boolList []bool
	if source != nil {
		boolList = make([]bool, len(source))
		for i := 0; i < len(source); i++ {
			boolList[i] = source[i]
		}
	}
	return boolList
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package b

type RootBImpl struct{}

func (c *RootBImpl) Convert(source []string) []string {
	var stringList []string
	if source != nil {
		stringList = make([]string, len(source))
		for i := 0; i < len(source); i++ {
			stringList[i] = source[i]
		}
	}
	return stringList
}

output:format

output:format FORMAT can be defined as CLI argument or conversion comment. Default struct

Specify the output FORMAT for the conversion methods. See Guide: Input/Output formats

output:format struct

Output an implementation of the conversion interface by creating a struct with methods.

Example (click me)
go
package house

import (
	"database/sql"

	"github.com/jmattheis/goverter/example/format/common"
)

// goverter:converter
// goverter:output:format struct
// goverter:extend SQLStringToPString
// goverter:extend ConvertToApartmentMap
type Converter interface {
	ConvertHouse(source common.DBHouse) common.APIHouse
	// goverter:map Owner.Name OwnerName
	ConvertApartment(source common.DBApartment) common.APIApartment
	// goverter:map Name FirstName
	// goverter:ignore Age
	ConvertPerson(source common.DBPerson) common.APIPerson
}

func SQLStringToPString(value sql.NullString) *string {
	if value.Valid {
		return &value.String
	}
	return nil
}

func ConvertToApartmentMap(c Converter, source []common.DBApartment) map[uint]common.APIApartment {
	m := make(map[uint]common.APIApartment)
	for _, apartment := range source {
		m[apartment.Position] = c.ConvertApartment(apartment) // !! this is not supported in some formats
	}
	return m
}
go
package common

import "database/sql"

type DBHouse struct {
	Address    string
	Apartments []DBApartment
}

type DBApartment struct {
	Position   uint
	Owner      DBPerson
	CoResident []DBPerson
}

type DBPerson struct {
	ID         int
	Name       string
	MiddleName sql.NullString
	Friends    []DBPerson
	Info       Info
}

type APIHouse struct {
	Address    string
	Apartments map[uint]APIApartment
}

type APIApartment struct {
	Position   uint
	Owner      APIPerson
	OwnerName  string
	CoResident []APIPerson
}

type APIPerson struct {
	ID         int
	MiddleName *string
	FirstName  *string
	Friends    []APIPerson
	Info       Info
	Age        int
}

type Info struct {
	Birthplace string
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import (
	common "github.com/jmattheis/goverter/example/format/common"
	interfacetostruct "github.com/jmattheis/goverter/example/format/interfacetostruct"
)

type ConverterImpl struct{}

func (c *ConverterImpl) ConvertApartment(source common.DBApartment) common.APIApartment {
	var commonAPIApartment common.APIApartment
	commonAPIApartment.Position = source.Position
	commonAPIApartment.Owner = c.ConvertPerson(source.Owner)
	commonAPIApartment.OwnerName = source.Owner.Name
	if source.CoResident != nil {
		commonAPIApartment.CoResident = make([]common.APIPerson, len(source.CoResident))
		for i := 0; i < len(source.CoResident); i++ {
			commonAPIApartment.CoResident[i] = c.ConvertPerson(source.CoResident[i])
		}
	}
	return commonAPIApartment
}
func (c *ConverterImpl) ConvertHouse(source common.DBHouse) common.APIHouse {
	var commonAPIHouse common.APIHouse
	commonAPIHouse.Address = source.Address
	commonAPIHouse.Apartments = interfacetostruct.ConvertToApartmentMap(c, source.Apartments)
	return commonAPIHouse
}
func (c *ConverterImpl) ConvertPerson(source common.DBPerson) common.APIPerson {
	var commonAPIPerson common.APIPerson
	commonAPIPerson.ID = source.ID
	commonAPIPerson.MiddleName = interfacetostruct.SQLStringToPString(source.MiddleName)
	pString := source.Name
	commonAPIPerson.FirstName = &pString
	if source.Friends != nil {
		commonAPIPerson.Friends = make([]common.APIPerson, len(source.Friends))
		for i := 0; i < len(source.Friends); i++ {
			commonAPIPerson.Friends[i] = c.ConvertPerson(source.Friends[i])
		}
	}
	commonAPIPerson.Info = c.commonInfoToCommonInfo(source.Info)
	return commonAPIPerson
}
func (c *ConverterImpl) commonInfoToCommonInfo(source common.Info) common.Info {
	var commonInfo common.Info
	commonInfo.Birthplace = source.Birthplace
	return commonInfo
}

output:format assign-variable

Output an init function assiging an implementation for all function variables.

Example (click me)
go
package house

import (
	"database/sql"

	"github.com/jmattheis/goverter/example/format/common"
)

// goverter:variables
// goverter:output:format assign-variable
// goverter:extend SQLStringToPString
// goverter:extend ConvertToApartmentMap
var (
	ConvertHouse func(source common.DBHouse) common.APIHouse
	// goverter:map Name FirstName
	// goverter:ignore Age
	ConvertPerson func(source common.DBPerson) common.APIPerson
	// goverter:map Owner.Name OwnerName
	ConvertApartment func(source common.DBApartment) common.APIApartment
)

func SQLStringToPString(value sql.NullString) *string {
	if value.Valid {
		return &value.String
	}
	return nil
}

func ConvertToApartmentMap(source []common.DBApartment) map[uint]common.APIApartment {
	m := make(map[uint]common.APIApartment)
	for _, apartment := range source {
		m[apartment.Position] = ConvertApartment(apartment) // !! this is not supported in some formats
	}
	return m
}
go
package common

import "database/sql"

type DBHouse struct {
	Address    string
	Apartments []DBApartment
}

type DBApartment struct {
	Position   uint
	Owner      DBPerson
	CoResident []DBPerson
}

type DBPerson struct {
	ID         int
	Name       string
	MiddleName sql.NullString
	Friends    []DBPerson
	Info       Info
}

type APIHouse struct {
	Address    string
	Apartments map[uint]APIApartment
}

type APIApartment struct {
	Position   uint
	Owner      APIPerson
	OwnerName  string
	CoResident []APIPerson
}

type APIPerson struct {
	ID         int
	MiddleName *string
	FirstName  *string
	Friends    []APIPerson
	Info       Info
	Age        int
}

type Info struct {
	Birthplace string
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package house

import common "github.com/jmattheis/goverter/example/format/common"

func init() {
	ConvertApartment = func(source common.DBApartment) common.APIApartment {
		var commonAPIApartment common.APIApartment
		commonAPIApartment.Position = source.Position
		commonAPIApartment.Owner = ConvertPerson(source.Owner)
		commonAPIApartment.OwnerName = source.Owner.Name
		if source.CoResident != nil {
			commonAPIApartment.CoResident = make([]common.APIPerson, len(source.CoResident))
			for i := 0; i < len(source.CoResident); i++ {
				commonAPIApartment.CoResident[i] = ConvertPerson(source.CoResident[i])
			}
		}
		return commonAPIApartment
	}
	ConvertHouse = func(source common.DBHouse) common.APIHouse {
		var commonAPIHouse common.APIHouse
		commonAPIHouse.Address = source.Address
		commonAPIHouse.Apartments = ConvertToApartmentMap(source.Apartments)
		return commonAPIHouse
	}
	ConvertPerson = func(source common.DBPerson) common.APIPerson {
		var commonAPIPerson common.APIPerson
		commonAPIPerson.ID = source.ID
		commonAPIPerson.MiddleName = SQLStringToPString(source.MiddleName)
		pString := source.Name
		commonAPIPerson.FirstName = &pString
		if source.Friends != nil {
			commonAPIPerson.Friends = make([]common.APIPerson, len(source.Friends))
			for i := 0; i < len(source.Friends); i++ {
				commonAPIPerson.Friends[i] = ConvertPerson(source.Friends[i])
			}
		}
		commonAPIPerson.Info = commonInfoToCommonInfo(source.Info)
		return commonAPIPerson
	}
}
func commonInfoToCommonInfo(source common.Info) common.Info {
	var commonInfo common.Info
	commonInfo.Birthplace = source.Birthplace
	return commonInfo
}

output:format function

Output a function for each method in the conversion interface.

Example (click me)
go
package house

import (
	"database/sql"

	"github.com/jmattheis/goverter/example/format/common"
)

// goverter:converter
// goverter:output:format function
// goverter:extend SQLStringToPString
type Converter interface {
	// goverter:map Owner.Name OwnerName
	ConvertApartment(source common.DBApartment) common.APIApartment
	// goverter:map Name FirstName
	// goverter:ignore Age
	ConvertPerson(source common.DBPerson) common.APIPerson
}

func SQLStringToPString(value sql.NullString) *string {
	if value.Valid {
		return &value.String
	}
	return nil
}
go
package common

import "database/sql"

type DBHouse struct {
	Address    string
	Apartments []DBApartment
}

type DBApartment struct {
	Position   uint
	Owner      DBPerson
	CoResident []DBPerson
}

type DBPerson struct {
	ID         int
	Name       string
	MiddleName sql.NullString
	Friends    []DBPerson
	Info       Info
}

type APIHouse struct {
	Address    string
	Apartments map[uint]APIApartment
}

type APIApartment struct {
	Position   uint
	Owner      APIPerson
	OwnerName  string
	CoResident []APIPerson
}

type APIPerson struct {
	ID         int
	MiddleName *string
	FirstName  *string
	Friends    []APIPerson
	Info       Info
	Age        int
}

type Info struct {
	Birthplace string
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import (
	common "github.com/jmattheis/goverter/example/format/common"
	interfacefunction "github.com/jmattheis/goverter/example/format/interfacefunction"
)

func ConvertApartment(source common.DBApartment) common.APIApartment {
	var commonAPIApartment common.APIApartment
	commonAPIApartment.Position = source.Position
	commonAPIApartment.Owner = ConvertPerson(source.Owner)
	commonAPIApartment.OwnerName = source.Owner.Name
	if source.CoResident != nil {
		commonAPIApartment.CoResident = make([]common.APIPerson, len(source.CoResident))
		for i := 0; i < len(source.CoResident); i++ {
			commonAPIApartment.CoResident[i] = ConvertPerson(source.CoResident[i])
		}
	}
	return commonAPIApartment
}
func ConvertPerson(source common.DBPerson) common.APIPerson {
	var commonAPIPerson common.APIPerson
	commonAPIPerson.ID = source.ID
	commonAPIPerson.MiddleName = interfacefunction.SQLStringToPString(source.MiddleName)
	pString := source.Name
	commonAPIPerson.FirstName = &pString
	if source.Friends != nil {
		commonAPIPerson.Friends = make([]common.APIPerson, len(source.Friends))
		for i := 0; i < len(source.Friends); i++ {
			commonAPIPerson.Friends[i] = ConvertPerson(source.Friends[i])
		}
	}
	commonAPIPerson.Info = commonInfoToCommonInfo(source.Info)
	return commonAPIPerson
}
func commonInfoToCommonInfo(source common.Info) common.Info {
	var commonInfo common.Info
	commonInfo.Birthplace = source.Birthplace
	return commonInfo
}

output:package

output:package [PACKAGE][:NAME] can be defined as CLI argument or conversion comment. Default is :generated.

output:package PACKAGE

This is the recommended way to define this setting. If you define the full package path, goverter is able to prevent edge-cases in the converter generation. The package name used in the generated .go file will be inferred from the normalized full package path. E.g.

go
// goverter:converter
// goverter:output:package example.org/simple/mypackage
type Converter interface {
    Convert([]string) []string
}

will create generated/generated.go starting with

go
package mypackage
// ...

If there are reserved characters in the package name will be normalized. E.g.

go
// goverter:converter
// goverter:output:package example.org/simple/my-cool_package
type Converter interface {
    Convert([]string) []string
}

will create generated/generated.go starting with

go
package mycoolpackage
// ...

output:package PACKAGE:NAME

If you want to overwrite the inferred package name, you can do so with output:package PACKAGE:NAME. E.g.

go
// goverter:converter
// goverter:output:package example.org/simple/my-cool_package:overriddenname
type Converter interface {
    Convert([]string) []string
}

will create generated/generated.go starting with

go
package overriddenname
// ...

output:package NAME

If you aren't able to define the full package path, then you can only define the package name with output:package :NAME. Goverter may produce uncompilable code, when you hit an edge-case that requires a full package path. If the generated code compiles, then there should be no problems using the setting like this.

go
// goverter:converter
// goverter:output:package :mypackage
type Converter interface {
    Convert([]string) []string
}

will create generated/generated.go starting with

go
package mypackage
// ...