Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions builder/assignto.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ func AssignOf(s *jen.Statement) *AssignTo {
}

func (a *AssignTo) WithIndex(s *jen.Statement) *AssignTo {
return &AssignTo{
Stmt: a.Stmt.Clone().Index(s),
}
return &AssignTo{Stmt: a.Stmt.Clone().Index(s)}
}

func (a *AssignTo) MustAssign() *AssignTo {
a.Must = true
return a
return &AssignTo{Stmt: a.Stmt, Must: true, Update: a.Update}
}

func (a *AssignTo) WithStmt(s *jen.Statement) *AssignTo {
return &AssignTo{Stmt: s, Must: a.Must, Update: a.Update}
}

func (a *AssignTo) IsUpdate() *AssignTo {
a.Update = true
return a
func (a *AssignTo) WithUpdate(update bool) *AssignTo {
return &AssignTo{Stmt: a.Stmt, Must: a.Must, Update: update}
}

func ToAssignable(assignTo *AssignTo) func(stmt []jen.Code, nextID *xtype.JenID, err *Error) ([]jen.Code, *Error) {
Expand All @@ -46,16 +46,16 @@ func AssignByBuild(b Builder, gen Generator, ctx *MethodContext, assignTo *Assig
}

func BuildByAssign(b Builder, gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) {
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
buildStmt, assignTo, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
if err != nil {
return nil, nil, err
}

stmt, err := b.Assign(gen, ctx, AssignOf(valueVar), sourceID, source, target, path)
stmt, err := b.Assign(gen, ctx, assignTo, sourceID, source, target, path)
if err != nil {
return nil, nil, err
}

buildStmt = append(buildStmt, stmt...)
return buildStmt, xtype.VariableID(valueVar), nil
return buildStmt, xtype.VariableID(assignTo.Stmt.Clone()), nil
}
8 changes: 4 additions & 4 deletions builder/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import (
"github.com/jmattheis/goverter/xtype"
)

func buildTargetVar(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *jen.Statement, *Error) {
func buildTargetVar(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *AssignTo, *Error) {
if !ctx.UseConstructor ||
!types.Identical(ctx.Conf.Source.T, source.T) ||
!types.Identical(ctx.Conf.Target.T, target.T) {
name := ctx.Name(target.ID())
variable := jen.Var().Id(name).Add(target.TypeAsJen())
ctx.SetErrorTargetVar(jen.Id(name))
return []jen.Code{variable}, jen.Id(name), nil
return []jen.Code{variable}, AssignOf(jen.Id(name)), nil
}
ctx.UseConstructor = false

Expand All @@ -37,10 +37,10 @@ func buildTargetVar(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, so

if nextID.Variable {
ctx.SetErrorTargetVar(nextID.Code.Clone())
return stmt, nextID.Code, nil
return stmt, AssignOf(nextID.Code).WithUpdate(ctx.Conf.DefaultUpdate), nil
}
name := ctx.Name(target.ID())
stmt = append(stmt, jen.Id(name).Op(":=").Add(nextID.Code))
ctx.SetErrorTargetVar(jen.Id(name))
return stmt, jen.Id(name), nil
return stmt, AssignOf(jen.Id(name)).WithUpdate(ctx.Conf.DefaultUpdate), nil
}
3 changes: 2 additions & 1 deletion builder/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ func isEnum(ctx *MethodContext, source, target *xtype.Type) bool {

// Build creates conversion source code for the given source and target type.
func (*Enum) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) {
stmt, nameVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
stmt, nameAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
if err != nil {
return nil, nil, err
}
nameVar := nameAssign.Stmt

var cases []jen.Code

Expand Down
18 changes: 9 additions & 9 deletions builder/pointer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ func (*Pointer) Matches(_ *MethodContext, source, target *xtype.Type) bool {
func (p *Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) {
ctx.SetErrorTargetVar(jen.Nil())
if ctx.UseConstructor && ctx.Conf.DefaultUpdate {
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, errPath)
buildStmt, valueAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, errPath)
if err != nil {
return nil, nil, err
}

stmt, err := gen.Assign(ctx, AssignOf(jen.Parens(jen.Op("*").Add(valueVar))).IsUpdate(), sourceID.Deref(source), source.PointerInner, target.PointerInner, errPath)
stmt, err := gen.Assign(ctx, valueAssign.WithStmt(jen.Parens(jen.Op("*").Add(valueAssign.Stmt.Clone()))), sourceID.Deref(source), source.PointerInner, target.PointerInner, errPath)
if err != nil {
return nil, nil, err.Lift(&Path{
SourceID: "*",
Expand All @@ -34,7 +34,7 @@ func (p *Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID

buildStmt = append(buildStmt, jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block(stmt...))

return buildStmt, xtype.VariableID(valueVar), nil
return buildStmt, xtype.VariableID(valueAssign.Stmt), nil
}

return BuildByAssign(p, gen, ctx, sourceID, source, target, errPath)
Expand Down Expand Up @@ -76,12 +76,12 @@ func (*SourcePointer) Matches(ctx *MethodContext, source, target *xtype.Type) bo
// Build creates conversion source code for the given source and target type.
func (s *SourcePointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, path ErrorPath) ([]jen.Code, *xtype.JenID, *Error) {
if ctx.UseConstructor && ctx.Conf.DefaultUpdate {
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
buildStmt, targetAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
if err != nil {
return nil, nil, err
}

stmt, err := gen.Assign(ctx, AssignOf(valueVar).IsUpdate(), sourceID.Deref(source), source.PointerInner, target, path)
stmt, err := gen.Assign(ctx, targetAssign, sourceID.Deref(source), source.PointerInner, target, path)
if err != nil {
return nil, nil, err.Lift(&Path{
SourceID: "*",
Expand All @@ -91,7 +91,7 @@ func (s *SourcePointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype

buildStmt = append(buildStmt, jen.If(sourceID.Code.Clone().Op("!=").Nil()).Block(stmt...))

return buildStmt, xtype.VariableID(valueVar), nil
return buildStmt, xtype.VariableID(targetAssign.Stmt), nil
}

return BuildByAssign(s, gen, ctx, sourceID, source, target, path)
Expand Down Expand Up @@ -127,12 +127,12 @@ func (*TargetPointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.J
ctx.SetErrorTargetVar(jen.Nil())

if ctx.UseConstructor {
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
buildStmt, targetAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
if err != nil {
return nil, nil, err
}

stmt, err := gen.Assign(ctx, AssignOf(jen.Parens(jen.Op("*").Add(valueVar))).IsUpdate(), sourceID, source, target.PointerInner, path)
stmt, err := gen.Assign(ctx, targetAssign.WithStmt(jen.Parens(jen.Op("*").Add(targetAssign.Stmt.Clone()))), sourceID, source, target.PointerInner, path)
if err != nil {
return nil, nil, err.Lift(&Path{
TargetID: "*",
Expand All @@ -142,7 +142,7 @@ func (*TargetPointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.J

buildStmt = append(buildStmt, stmt...)

return buildStmt, xtype.VariableID(valueVar), nil
return buildStmt, xtype.VariableID(targetAssign.Stmt), nil
}

stmt, id, err := gen.Build(ctx, sourceID, source, target.PointerInner, path)
Expand Down
5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import GH from './GH.vue';

## unreleased

## v1.9.4

- Fix [`default:update`](./reference/default.md) not applying zero value checks
for non-pointer source and target types. <GH issue="221" pr="222"/>

## v1.9.3

- Allow unexported [`extend`](./reference/extend.md) functions with inferred
Expand Down
53 changes: 53 additions & 0 deletions scenario/default_update_non_pointer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
input:
input.go: |
package execution

import "time"

type Source struct {
Age int
Name *string
Start *time.Time
}

type Dest struct {
Age int
Name *string
Start *time.Time
}

// goverter:converter
// goverter:default:update
// goverter:update:ignoreZeroValueField yes
// goverter:skipCopySameType yes
type testConverter interface {
// goverter:default DefaultParams
ToDest(source Source) Dest
}

func DefaultParams() Dest {
return Dest{Age: 10, Name: nil, Start: nil}
}
success:
- generated/generated.go: |
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.

package generated

import execution "github.com/jmattheis/goverter/execution"

type testConverterImpl struct{}

func (c *testConverterImpl) ToDest(source execution.Source) execution.Dest {
executionDest := execution.DefaultParams()
if source.Age != 0 {
executionDest.Age = source.Age
}
if source.Name != nil {
executionDest.Name = source.Name
}
if source.Start != nil {
executionDest.Start = source.Start
}
return executionDest
}
53 changes: 53 additions & 0 deletions scenario/default_update_non_ptr_to_ptr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
input:
input.go: |
package execution

import "time"

type Source struct {
Age int
Name *string
Start *time.Time
}

type Dest struct {
Age int
Name *string
Start *time.Time
}

// goverter:converter
// goverter:default:update
// goverter:update:ignoreZeroValueField yes
// goverter:skipCopySameType yes
type testConverter interface {
// goverter:default DefaultParams
ToDest(source Source) *Dest
}

func DefaultParams() *Dest {
return &Dest{Age: 10, Name: nil, Start: nil}
}
success:
- generated/generated.go: |
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.

package generated

import execution "github.com/jmattheis/goverter/execution"

type testConverterImpl struct{}

func (c *testConverterImpl) ToDest(source execution.Source) *execution.Dest {
pExecutionDest := execution.DefaultParams()
if source.Age != 0 {
(*pExecutionDest).Age = source.Age
}
if source.Name != nil {
(*pExecutionDest).Name = source.Name
}
if source.Start != nil {
(*pExecutionDest).Start = source.Start
}
return pExecutionDest
}
55 changes: 55 additions & 0 deletions scenario/default_update_ptr_to_ptr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
input:
input.go: |
package execution

import "time"

type Source struct {
Age int
Name *string
Start *time.Time
}

type Dest struct {
Age int
Name *string
Start *time.Time
}

// goverter:converter
// goverter:default:update
// goverter:update:ignoreZeroValueField yes
// goverter:skipCopySameType yes
type testConverter interface {
// goverter:default DefaultParams
ToDest(source *Source) *Dest
}

func DefaultParams() *Dest {
return &Dest{Age: 10, Name: nil, Start: nil}
}
success:
- generated/generated.go: |
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.

package generated

import execution "github.com/jmattheis/goverter/execution"

type testConverterImpl struct{}

func (c *testConverterImpl) ToDest(source *execution.Source) *execution.Dest {
pExecutionDest := execution.DefaultParams()
if source != nil {
if (*source).Age != 0 {
(*pExecutionDest).Age = (*source).Age
}
if (*source).Name != nil {
(*pExecutionDest).Name = (*source).Name
}
if (*source).Start != nil {
(*pExecutionDest).Start = (*source).Start
}
}
return pExecutionDest
}
Loading