goverter
a "type-safe Go converter" generator
goverter is a tool for creating type-safe converters. All you have to do is create an interface and execute goverter. The project is meant as alternative to jinzhu/copier that doesn't use reflection.
Features
- Automatic conversion of builtin types (
house
example), this includes:- slices, maps, named types, primitive types, pointers
- structs with same fields
- Extend parts of the conversion with your own implementation: Docs
- Optional return of an error: Docs
- Awesome error messages: mismatch type test
- No reflection in the generated code
Usage
-
Create a go modules project if you haven't done so already
$ go mod init module-name
-
Add
goverter
as dependency to your project$ go get github.com/jmattheis/goverter
-
Create your converter interface and mark it with a comment containing
goverter:converter
input.go
package example // goverter:converter type Converter interface { Convert(source []Input) []Output } type Input struct { Name string Age int } type Output struct { Name string Age int }
-
Run
goverter
:$ go run github.com/jmattheis/goverter/cmd/goverter module-name-in-full # example $ go run github.com/jmattheis/goverter/cmd/goverter github.com/jmattheis/goverter/example/simple
-
goverter created a file at
./generated/generated.go
, it may look like this:package generated import simple "github.com/jmattheis/goverter/example/simple" type ConverterImpl struct{} func (c *ConverterImpl) Convert(source []simple.Input) []simple.Output { simpleOutputList := make([]simple.Output, len(source)) for i := 0; i < len(source); i++ { simpleOutputList[i] = c.simpleInputToSimpleOutput(source[i]) } return simpleOutputList } func (c *ConverterImpl) simpleInputToSimpleOutput(source simple.Input) simple.Output { var simpleOutput simple.Output simpleOutput.Name = source.Name simpleOutput.Age = source.Age return simpleOutput }
Docs
Rename converter
With goverter:name
you can set the name of the generated converter struct.
input.go
// goverter:converter
// goverter:name RenamedConverter
type BadlyNamed interface {
// .. methods
}
output.go
type RenamedConverter struct {}
func (c *RenamedConverter) ...
Extend with custom implementation
With goverter:extend
you can instruct goverter to use an implementation of your own. You can pass multiple function names to goverter:extend
, or define the tag multiple times.
See house
example sql.NullString
input.go
// goverter:converter
// goverter:extend IntToString
type Converter interface {
Convert(Input) Output
}
type Input struct {Value int}
type Output struct {Value string}
// You must atleast define a source and target type. Meaning one parameter and one return.
// You can use any type you want, like struct, maps and so on.
func IntToString(i int) string {
return fmt.Sprint(i)
}
Reuse generated converter
If you need access to the generated converter, you can define it as first parameter.
func IntToString(c Converter, i int) string {
// c.DoSomething()..
return fmt.Sprint(i)
}
Errors
Sometimes, custom conversion may fail, in this case goverter allows you to define a second return parameter which must be type error
.
// goverter:converter
// goverter:extend IntToString
type Converter interface {
Convert(Input) (Output, error)
}
type Input struct {Value int}
type Output struct {Value string}
func IntToString(i int) (string, error) {
if i == 0 {
return "", errors.New("zero is not allowed")
}
return fmt.Sprint(i)
}
Note: If you do this, methods on the interface that'll use this custom implementation, must also return error as second return.
Struct field mapping
With goverter:map
you can map fields on a struct that have the same type but different names.
goverter:map
takes 2 parameters.
- source field name
- target field name
// goverter:converter
type Converter interface {
// goverter:map Name FullName
Convert(source Input) Output
}
type Input struct {
Name string
Age int
}
type Output struct {
FullName string
Age int
}
Struct ignore field
With goverter:ignore
you can ignore fields on the target struct
goverter:ignore
takes multiple field names separated by space
.
// goverter:converter
type Converter interface {
// goverter:ignore Age
Convert(source Input) Output
}
type Input struct {
Name string
}
type Output struct {
Name string
Age int
}
Versioning
goverter use SemVer for versioning the cli.
License
This project is licensed under the MIT License - see the LICENSE file for details
Logo by MariaLetta