Generate output into the same package
To output the generated implementation into the package containing the converter interface you can follow these steps:
Configure generation
Configure output
to output the file into the same directory, define the full package path, and then run goverter gen
.
go
package samepackage
// goverter:converter
// goverter:output:file ./generated.go
// goverter:output:package github.com/jmattheis/goverter/example/samepackage
type Converter interface {
Convert(source *Input) *Output
}
type Input struct{ Name string }
type Output struct{ Name string }
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package samepackage
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source *Input) *Output {
var pSamepackageOutput *Output
if source != nil {
var samepackageOutput Output
samepackageOutput.Name = (*source).Name
pSamepackageOutput = &samepackageOutput
}
return pSamepackageOutput
}
Use implementation
Goverter will ignore files generated by goverter when generating the implementation. (See Build Constraint)
This means if you want to use the implementation in the same package e.g
go
package samepackage
import "errors"
func ValidateAndConvert(source *Input) (*Output, error) {
if source.Name == "" {
return nil, errors.New("Name may not be nil")
}
c := &ConverterImpl{}
return c.Convert(source)
}
Goverter will fail with an complilation error like this:
could not load package github.com/jmattheis/goverter/example/samepackage
-: # github.com/jmattheis/goverter/example/samepackage
samepackage/use.go:12:8: undefined: ConverterImpl
Goverter cannot generate converters when there are compile errors because it
requires the type information from the compiled sources.
You can fix this by adding the Build Constraint to the newly added file like this:
go
//go:build !goverter
package samepackage
import "errors"
func ValidateAndConvert(source *Input) (*Output, error) {
if source.Name == "" {
return nil, errors.New("Name may not be nil")
}
c := &ConverterImpl{}
output := c.Convert(source)
return output, nil
}
go
package samepackage
// goverter:converter
// goverter:output:file ./generated.go
// goverter:output:package github.com/jmattheis/goverter/example/samepackage
type Converter interface {
Convert(source *Input) *Output
}
type Input struct{ Name string }
type Output struct{ Name string }
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package samepackage
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source *Input) *Output {
var pSamepackageOutput *Output
if source != nil {
var samepackageOutput Output
samepackageOutput.Name = (*source).Name
pSamepackageOutput = &samepackageOutput
}
return pSamepackageOutput
}
or by defining a global variable with the type of the interface and then assigning it in a different file containing a Build Constraint.
go
package samepackage
import "errors"
var c Converter
func ValidateAndConvert2(source *Input) (*Output, error) {
if source.Name == "" {
return nil, errors.New("Name may not be nil")
}
output := c.Convert(source)
return output, nil
}
go
//go:build !goverter
package samepackage
func init() {
c = &ConverterImpl{}
}
go
package samepackage
// goverter:converter
// goverter:output:file ./generated.go
// goverter:output:package github.com/jmattheis/goverter/example/samepackage
type Converter interface {
Convert(source *Input) *Output
}
type Input struct{ Name string }
type Output struct{ Name string }
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter
package samepackage
type ConverterImpl struct{}
func (c *ConverterImpl) Convert(source *Input) *Output {
var pSamepackageOutput *Output
if source != nil {
var samepackageOutput Output
samepackageOutput.Name = (*source).Name
pSamepackageOutput = &samepackageOutput
}
return pSamepackageOutput
}