Skip to content

Signature

Goverter supports a variety of different signatures.

Definition

In Go a function has params and results. E.g.

go
type Converter interface {
    Convert(A, B) (C, D)
}
  • A and B are params
  • C and C are results or returns

Named params/results

Go allows you to specify names to params and results. This document references them as "named params" / "named results".

go
type Converter interface {
    Convert(nameA A, nameB B) (nameC C, nameD D)
}

Categories

Goverter groups params and results into these categories:

  1. source is a param that will be converted to the target type. Any param that is not a context type is a source type.
  2. target is the first result or the argument defined with update which sources are converted to.
  3. target_error is the second result type which can be specified if the conversion fails. target_error must be of type error
  4. context are named params where the argument is defined with context. Or matching the regex arg:context:regex They are used in custom functions for manual conversion. context types aren't used for automatic conversion.

Default context

If you are using goverter:converter, then the conversion interface seen as context regardless of the param name.

Supported Signatures

Signature: Conversion Method

Depending on the output:format, a conversion method is defined on an interface, e.g. ConvertA or as variable, e.g. ConvertB:

go
// goverter:converter
type Converter interface {
    ConvertA(Input) Output
}
// goverter:variables
var (
    ConvertB func(Input) Output
)

Conversion methods support the following categories:

  • source: required
  • context: optional (multiple), a conversion method may have zero or more context types
  • target: required
  • target_error: optional

Here are signatures that would satisfy the given requirements:

go
// goverter:converter
type Converter interface {
    ConvertOne(A) B
    // A=source; B=target

    ConvertTwo(source A) (B, error)
    // A=source; B=target; error=target_error

    // goverter:context b
    ConvertThree(source A, b B) C
    // A=source; B=context; B=target

    // goverter:context one
    // goverter:context two
    ConvertFour(one A, source B, two C) (D, error)
    // A=context; B=source; C=context; D=target; error=target_error
}
Example (click to expand)
go
package example

// goverter:converter
type Converter interface {
	// goverter:map ID Editable | QueryEditable
	// goverter:context db
	Convert(source PostInput, db Database) (PostOutput, error)
}

// goverter:context db
func QueryEditable(id int, db Database) bool {
	return db.AllowedToEdit(id)
}

type Database interface {
	AllowedToEdit(id int) bool
}

type PostInput struct {
	ID   int
	Body string
}
type PostOutput struct {
	ID       int
	Body     string
	Editable bool
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import database "github.com/jmattheis/goverter/example/context/database"

type ConverterImpl struct{}

func (c *ConverterImpl) Convert(source database.PostInput, context database.Database) (database.PostOutput, error) {
	var examplePostOutput database.PostOutput
	examplePostOutput.ID = source.ID
	examplePostOutput.Body = source.Body
	examplePostOutput.Editable = database.QueryEditable(source.ID, context)
	return examplePostOutput, nil
}

Signature: Update Conversion Method

When update is configured, the target type of the conversion signature must be inside the arguments, and the target type must be of type *T where T is any struct. The source type may be T or *T where T is any struct.

go
// goverter:converter
type Converter interface {
    ConvertOne(source A, target B)
    // A=source; B=target
    ConvertTwo(source A, target B) error
    // A=source; B=target; error=target_error
    // goverter:context ctx
    ConvertThree(target A, source B, ctx C)
    // A=target; B=source; C=context
}

Signature: optional source

The settings default and map CUSTOM support the following categories:

  • source: optional
  • context: optional (multiple), may have zero or more context types
  • target: required
  • target_error: optional

Here are signatures that would satisfy the given requirements:

go
func ConvertOne() A {/**/}
// A=target

func ConvertTwo() (B, error) {/**/}
// A=target; error=target_error

func ConvertThree(input A) B {/**/}
// A=source; B=target

func ConvertFour(input A) (B, error) {/**/}
// A=source; B=target; error=target_error

// goverter:context one
// goverter:context two
func ConvertFour(one A, two B) C {/**/}
// A=context; B=context; C=target

// goverter:context one
// goverter:context two
func ConvertFive(input A, one B, two C) D {/**/}
// A=source; B=context; C=context; D=target
Example (click to expand)
go
package example

// goverter:converter
type Converter interface {
	// goverter:map ID Editable | QueryEditable
	// goverter:context db
	Convert(source PostInput, db Database) (PostOutput, error)
}

// goverter:context db
func QueryEditable(id int, db Database) bool {
	return db.AllowedToEdit(id)
}

type Database interface {
	AllowedToEdit(id int) bool
}

type PostInput struct {
	ID   int
	Body string
}
type PostOutput struct {
	ID       int
	Body     string
	Editable bool
}
go
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
//go:build !goverter

package generated

import database "github.com/jmattheis/goverter/example/context/database"

type ConverterImpl struct{}

func (c *ConverterImpl) Convert(source database.PostInput, context database.Database) (database.PostOutput, error) {
	var examplePostOutput database.PostOutput
	examplePostOutput.ID = source.ID
	examplePostOutput.Body = source.Body
	examplePostOutput.Editable = database.QueryEditable(source.ID, context)
	return examplePostOutput, nil
}

Signature: required source

extend supports the following categories:

  • source: required
  • context: optional (multiple), may have zero or more context types
  • target: required
  • target_error: optional

Here are signatures that would satisfy the given requirements:

go
func ConvertOne(input A) B {/**/}
// A=source; B=target

func ConvertTwo(input A) (B, error) {/**/}
// A=source; B=target; error=target_error

// goverter:context one
func ConvertThree(input A, one B) C {/**/}
// A=source; B=context; C=target

// goverter:context one
// goverter:context two
func ConvertFour(input A, one B, two C) D {/**/}
// A=source; B=context; C=context; D=target

// goverter:context one
// goverter:context two
func ConvertFive(one A, source B, two C) (D, error) {/**/}
// A=context; B=source; C=context; D=target; error=target_error
Example (click to expand)
go
package example

import "time"

// goverter:converter
// goverter:extend FormatTime
type Converter interface {
	// goverter:context dateFormat
	Convert(source map[string]Input, dateFormat string) map[string]Output
}

// goverter:context dateFormat
func FormatTime(t time.Time, dateFormat string) string {
	return t.Format(dateFormat)
}

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
}