Skip to content

Commit 279ca7c

Browse files
committed
fix: update not applying zero value checks
1 parent e5e4ffd commit 279ca7c

8 files changed

Lines changed: 191 additions & 23 deletions

File tree

builder/assignto.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,21 @@ func AssignOf(s *jen.Statement) *AssignTo {
1717

1818
func (a *AssignTo) WithIndex(s *jen.Statement) *AssignTo {
1919
return &AssignTo{
20-
Stmt: a.Stmt.Clone().Index(s),
20+
Stmt: a.Stmt.Clone().Index(s),
21+
Update: a.Update,
2122
}
2223
}
2324

2425
func (a *AssignTo) MustAssign() *AssignTo {
25-
a.Must = true
26-
return a
26+
return &AssignTo{Stmt: a.Stmt, Must: true, Update: a.Update}
2727
}
2828

29-
func (a *AssignTo) IsUpdate() *AssignTo {
30-
a.Update = true
31-
return a
29+
func (a *AssignTo) SetStmt(s *jen.Statement) *AssignTo {
30+
return &AssignTo{Stmt: s, Must: a.Must, Update: a.Update}
31+
}
32+
33+
func (a *AssignTo) SetUpdate(update bool) *AssignTo {
34+
return &AssignTo{Stmt: a.Stmt, Must: a.Must, Update: update}
3235
}
3336

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

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

54-
stmt, err := b.Assign(gen, ctx, AssignOf(valueVar), sourceID, source, target, path)
57+
stmt, err := b.Assign(gen, ctx, assignTo, sourceID, source, target, path)
5558
if err != nil {
5659
return nil, nil, err
5760
}
5861

5962
buildStmt = append(buildStmt, stmt...)
60-
return buildStmt, xtype.VariableID(valueVar), nil
63+
return buildStmt, xtype.VariableID(assignTo.Stmt.Clone()), nil
6164
}

builder/default.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import (
77
"github.com/jmattheis/goverter/xtype"
88
)
99

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

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

3838
if nextID.Variable {
3939
ctx.SetErrorTargetVar(nextID.Code.Clone())
40-
return stmt, nextID.Code, nil
40+
return stmt, AssignOf(nextID.Code).SetUpdate(ctx.Conf.DefaultUpdate), nil
4141
}
4242
name := ctx.Name(target.ID())
4343
stmt = append(stmt, jen.Id(name).Op(":=").Add(nextID.Code))
4444
ctx.SetErrorTargetVar(jen.Id(name))
45-
return stmt, jen.Id(name), nil
45+
return stmt, AssignOf(jen.Id(name)).SetUpdate(ctx.Conf.DefaultUpdate), nil
4646
}

builder/enum.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ func isEnum(ctx *MethodContext, source, target *xtype.Type) bool {
2525

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

3334
var cases []jen.Code
3435

builder/pointer.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ func (*Pointer) Matches(_ *MethodContext, source, target *xtype.Type) bool {
1717
func (p *Pointer) Build(gen Generator, ctx *MethodContext, sourceID *xtype.JenID, source, target *xtype.Type, errPath ErrorPath) ([]jen.Code, *xtype.JenID, *Error) {
1818
ctx.SetErrorTargetVar(jen.Nil())
1919
if ctx.UseConstructor && ctx.Conf.DefaultUpdate {
20-
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, errPath)
20+
buildStmt, valueAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, errPath)
2121
if err != nil {
2222
return nil, nil, err
2323
}
2424

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

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

37-
return buildStmt, xtype.VariableID(valueVar), nil
37+
return buildStmt, xtype.VariableID(valueAssign.Stmt), nil
3838
}
3939

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

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

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

94-
return buildStmt, xtype.VariableID(valueVar), nil
94+
return buildStmt, xtype.VariableID(targetAssign.Stmt), nil
9595
}
9696

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

129129
if ctx.UseConstructor {
130-
buildStmt, valueVar, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
130+
buildStmt, targetAssign, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
131131
if err != nil {
132132
return nil, nil, err
133133
}
134134

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

143143
buildStmt = append(buildStmt, stmt...)
144144

145-
return buildStmt, xtype.VariableID(valueVar), nil
145+
return buildStmt, xtype.VariableID(targetAssign.Stmt), nil
146146
}
147147

148148
stmt, id, err := gen.Build(ctx, sourceID, source, target.PointerInner, path)

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import GH from './GH.vue';
66

77
## unreleased
88

9+
- Fix [`default:update`](./reference/default.md) not applying zero value checks
10+
for non-pointer source and target types. <GH issue="221" pr="222"/>
11+
912
## v1.9.3
1013

1114
- Allow unexported [`extend`](./reference/extend.md) functions with inferred
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
input:
2+
input.go: |
3+
package execution
4+
5+
import "time"
6+
7+
type Source struct {
8+
Age int
9+
Name *string
10+
Start *time.Time
11+
}
12+
13+
type Dest struct {
14+
Age int
15+
Name *string
16+
Start *time.Time
17+
}
18+
19+
// goverter:converter
20+
// goverter:default:update
21+
// goverter:update:ignoreZeroValueField yes
22+
// goverter:skipCopySameType yes
23+
type testConverter interface {
24+
// goverter:default DefaultParams
25+
ToDest(source Source) Dest
26+
}
27+
28+
func DefaultParams() Dest {
29+
return Dest{Age: 10, Name: nil, Start: nil}
30+
}
31+
success:
32+
- generated/generated.go: |
33+
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
34+
35+
package generated
36+
37+
import execution "github.com/jmattheis/goverter/execution"
38+
39+
type testConverterImpl struct{}
40+
41+
func (c *testConverterImpl) ToDest(source execution.Source) execution.Dest {
42+
executionDest := execution.DefaultParams()
43+
if source.Age != 0 {
44+
executionDest.Age = source.Age
45+
}
46+
if source.Name != nil {
47+
executionDest.Name = source.Name
48+
}
49+
if source.Start != nil {
50+
executionDest.Start = source.Start
51+
}
52+
return executionDest
53+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
input:
2+
input.go: |
3+
package execution
4+
5+
import "time"
6+
7+
type Source struct {
8+
Age int
9+
Name *string
10+
Start *time.Time
11+
}
12+
13+
type Dest struct {
14+
Age int
15+
Name *string
16+
Start *time.Time
17+
}
18+
19+
// goverter:converter
20+
// goverter:default:update
21+
// goverter:update:ignoreZeroValueField yes
22+
// goverter:skipCopySameType yes
23+
type testConverter interface {
24+
// goverter:default DefaultParams
25+
ToDest(source Source) *Dest
26+
}
27+
28+
func DefaultParams() *Dest {
29+
return &Dest{Age: 10, Name: nil, Start: nil}
30+
}
31+
success:
32+
- generated/generated.go: |
33+
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
34+
35+
package generated
36+
37+
import execution "github.com/jmattheis/goverter/execution"
38+
39+
type testConverterImpl struct{}
40+
41+
func (c *testConverterImpl) ToDest(source execution.Source) *execution.Dest {
42+
pExecutionDest := execution.DefaultParams()
43+
if source.Age != 0 {
44+
(*pExecutionDest).Age = source.Age
45+
}
46+
if source.Name != nil {
47+
(*pExecutionDest).Name = source.Name
48+
}
49+
if source.Start != nil {
50+
(*pExecutionDest).Start = source.Start
51+
}
52+
return pExecutionDest
53+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
input:
2+
input.go: |
3+
package execution
4+
5+
import "time"
6+
7+
type Source struct {
8+
Age int
9+
Name *string
10+
Start *time.Time
11+
}
12+
13+
type Dest struct {
14+
Age int
15+
Name *string
16+
Start *time.Time
17+
}
18+
19+
// goverter:converter
20+
// goverter:default:update
21+
// goverter:update:ignoreZeroValueField yes
22+
// goverter:skipCopySameType yes
23+
type testConverter interface {
24+
// goverter:default DefaultParams
25+
ToDest(source *Source) *Dest
26+
}
27+
28+
func DefaultParams() *Dest {
29+
return &Dest{Age: 10, Name: nil, Start: nil}
30+
}
31+
success:
32+
- generated/generated.go: |
33+
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
34+
35+
package generated
36+
37+
import execution "github.com/jmattheis/goverter/execution"
38+
39+
type testConverterImpl struct{}
40+
41+
func (c *testConverterImpl) ToDest(source *execution.Source) *execution.Dest {
42+
pExecutionDest := execution.DefaultParams()
43+
if source != nil {
44+
if (*source).Age != 0 {
45+
(*pExecutionDest).Age = (*source).Age
46+
}
47+
if (*source).Name != nil {
48+
(*pExecutionDest).Name = (*source).Name
49+
}
50+
if (*source).Start != nil {
51+
(*pExecutionDest).Start = (*source).Start
52+
}
53+
}
54+
return pExecutionDest
55+
}

0 commit comments

Comments
 (0)