Skip to content

Commit a7d0f0f

Browse files
authored
Merge pull request #222 from jmattheis/fix-default-update-non-pointer
fix: update not applying zero value checks
2 parents e5e4ffd + f64844e commit a7d0f0f

File tree

8 files changed

+192
-25
lines changed

8 files changed

+192
-25
lines changed

builder/assignto.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ func AssignOf(s *jen.Statement) *AssignTo {
1616
}
1717

1818
func (a *AssignTo) WithIndex(s *jen.Statement) *AssignTo {
19-
return &AssignTo{
20-
Stmt: a.Stmt.Clone().Index(s),
21-
}
19+
return &AssignTo{Stmt: a.Stmt.Clone().Index(s)}
2220
}
2321

2422
func (a *AssignTo) MustAssign() *AssignTo {
25-
a.Must = true
26-
return a
23+
return &AssignTo{Stmt: a.Stmt, Must: true, Update: a.Update}
24+
}
25+
26+
func (a *AssignTo) WithStmt(s *jen.Statement) *AssignTo {
27+
return &AssignTo{Stmt: s, Must: a.Must, Update: a.Update}
2728
}
2829

29-
func (a *AssignTo) IsUpdate() *AssignTo {
30-
a.Update = true
31-
return a
30+
func (a *AssignTo) WithUpdate(update bool) *AssignTo {
31+
return &AssignTo{Stmt: a.Stmt, Must: a.Must, Update: update}
3232
}
3333

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

4848
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)
49+
buildStmt, assignTo, err := buildTargetVar(gen, ctx, sourceID, source, target, path)
5050
if err != nil {
5151
return nil, nil, err
5252
}
5353

54-
stmt, err := b.Assign(gen, ctx, AssignOf(valueVar), sourceID, source, target, path)
54+
stmt, err := b.Assign(gen, ctx, assignTo, sourceID, source, target, path)
5555
if err != nil {
5656
return nil, nil, err
5757
}
5858

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

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).WithUpdate(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)).WithUpdate(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.WithStmt(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.WithStmt(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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import GH from './GH.vue';
66

77
## unreleased
88

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

1116
- 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)