Skip to content

Commit

Permalink
BUG/MAJOR: equal: check for nil before calling equal
Browse files Browse the repository at this point in the history
on models that have Equal method we need to check first if any of the values is nil
  • Loading branch information
oktalz committed Dec 1, 2023
1 parent f1632f3 commit 3b9aa03
Show file tree
Hide file tree
Showing 21 changed files with 2,823 additions and 153 deletions.
11 changes: 6 additions & 5 deletions cmd/struct_equal_generator/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (

func generateEqualAndDiff(opt generateEqualAndDiffOptions) error {
funcMaps := template.FuncMap{
"HasPrefix": strings.HasPrefix,
"Title": toTitle,
"CamelCase": toCamelCase,
"LowerCase": toLowerCase,
"JSON": toJSON,
"HasPrefix": strings.HasPrefix,
"TrimPrefix": strings.TrimPrefix,
"Title": toTitle,
"CamelCase": toCamelCase,
"LowerCase": toLowerCase,
"JSON": toJSON,
}
tmpl, err := template.New("generate.tmpl").Funcs(funcMaps).Parse(tmplEqualAndDiff)
if err != nil {
Expand Down
38 changes: 37 additions & 1 deletion cmd/struct_equal_generator/generate.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,43 @@ func (s {{.Data.Name}}) {{.Name}}(t {{.Data.Name}}, opts ...Options) {{- if eq $
{{- end }}
}
{{- else if or .HasEqual .HasEqualOpt }}
if !s.{{.Name}}.Equal({{if HasPrefix .Type "*"}}*{{end}}t.{{.Name}}{{if .HasEqualOpt}}, opt{{end}}) {
{{if HasPrefix .Type "*"}}
if s.{{.Name}} == nil || t.{{.Name}} == nil {
if s.{{.Name}} != nil || t.{{.Name}} != nil {
if opt.NilSameAsEmpty {
{{- if eq .TypeInFile "" }}
empty := &{{ TrimPrefix .Type "*"}}{}
{{- else }}
empty := &{{ TrimPrefix .TypeInFile "*"}}{}
{{- end }}
if s.{{.Name}} == nil {
if !(t.{{.Name}}.Equal(*empty)){
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ {{if HasPrefix .Type "*"}}ValueOrNil({{end}}s.{{.Name}}{{if HasPrefix .Type "*"}}){{end}}, {{if HasPrefix .Type "*"}}ValueOrNil({{end}}t.{{.Name}}{{if HasPrefix .Type "*"}}){{end}} }
{{- end }}
}
}
if t.{{.Name}} == nil {
if !(s.{{.Name}}.Equal(*empty)){
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ {{if HasPrefix .Type "*"}}ValueOrNil({{end}}s.{{.Name}}{{if HasPrefix .Type "*"}}){{end}}, {{if HasPrefix .Type "*"}}ValueOrNil({{end}}t.{{.Name}}{{if HasPrefix .Type "*"}}){{end}} }
{{- end }}
}
}
} else {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ {{if HasPrefix .Type "*"}}ValueOrNil({{end}}s.{{.Name}}{{if HasPrefix .Type "*"}}){{end}}, {{if HasPrefix .Type "*"}}ValueOrNil({{end}}t.{{.Name}}{{if HasPrefix .Type "*"}}){{end}} }
{{- end }}
}
}
{{- end}}
{{if HasPrefix .Type "*"}} } else {{end}}if !s.{{.Name}}.Equal({{if HasPrefix .Type "*"}}*{{end}}t.{{.Name}}{{if .HasEqualOpt}}, opt{{end}}) {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
Expand Down
8 changes: 7 additions & 1 deletion cmd/struct_equal_generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func scanAllTypes(fileName string) []string {
return typesInFile
}

func generate(fileName string, args Args) (string, error) { //nolint:gocognit
func generate(fileName string, args Args) (string, error) { //nolint:gocognit,maintidx
fset := token.NewFileSet()
var packageName string

Expand Down Expand Up @@ -165,6 +165,12 @@ func generate(fileName string, args Args) (string, error) { //nolint:gocognit
needsOptions := false
needsOptionsIndex := false
fields, needsOptions, needsOptionsIndex = getFields(fields, currType, imports)
for _, f := range fields {
if strings.HasPrefix(f.Type, "*") && (f.HasEqualOpt || f.HasEqual) {
needsOptions = true
break
}
}
hasTests = true
err = generateEqualAndDiff(generateEqualAndDiffOptions{
PackageName: packageName,
Expand Down
Loading

0 comments on commit 3b9aa03

Please sign in to comment.