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
}