Skip to content

How to pass context to custom functions

You can pass additional parameters to custom functions by defining them as context.

If we want to format a time.Time to string but have requirements so that the date format must be changeable at runtime. You can define the time format as context, and then use it in a custom extend function.

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
}

Similarly, you could supply a database handle and query additional values that are needed in the target but missing in the source. E.g. in this example if a specific post is editable:

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
}