Skip to content

Commit

Permalink
MEDIUM: enhance struct_equal_generator for v3 model
Browse files Browse the repository at this point in the history
Co-authored-by:  Zlatko Bratkovic <[email protected]>
  • Loading branch information
hdurand0710 and oktalz committed Feb 2, 2024
1 parent 4f08fee commit 9a0d8d5
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 11 deletions.
46 changes: 38 additions & 8 deletions cmd/struct_equal_generator/generate.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,44 @@ func (s {{.Data.Name}}) {{.Name}}(t {{.Data.Name}}, opts ...Options) {{- if eq $
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 HasPrefix .Type "map" }}
{{- if eq .Type "map[string]map[string]string"}}
if !equalMapStringMapSting(s.{{.Name}}, t.{{.Name}}, opt) {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ s.{{.Name}}, t.{{.Name}}}
{{- end }}
}
{{- else }}
{{- if not .IsComparable }}
if !CheckSameNilAndLenMap[{{.MapKeyType}},{{.MapItemType}}](s.{{.Name}}, t.{{.Name}}, opt){
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ s.{{.Name}}, t.{{.Name}}}
{{- end }}
}

for k,v := range s.{{.Name}} {
if !t.{{.Name}}[k].Equal(v, opt) {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ s.{{.Name}}, t.{{.Name}}}
{{- end }}
}
}
{{- else }}
if !equalComparableMap(s.{{.Name}}, t.{{.Name}}, opt) {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ s.{{.Name}}, t.{{.Name}}}
{{- end }}
}
{{- end }}
{{- end }}
{{- else if or .IsBasicType .IsComparable}}
{{- if HasPrefix .Type "*" }}
if !equalPointers(s.{{.Name}}, t.{{.Name}}) {
Expand All @@ -101,14 +139,6 @@ func (s {{.Data.Name}}) {{.Name}}(t {{.Data.Name}}, opts ...Options) {{- if eq $
{{- end }}
}
{{- end }}
{{- else if HasPrefix .Type "map" }}
if !equalComparableMap(s.{{.Name}}, t.{{.Name}}, opt) {
{{- if eq $topLevel.Name "Equal" }}
return false
{{- else if eq $topLevel.Name "Diff" }}
diff["{{.Name}}"] = []interface{}{ s.{{.Name}}, t.{{.Name}}}
{{- end }}
}
{{- else if .IsArray }}
{{- if or .IsComparable .SubType.IsComparable }}
if !equalComparableSlice(s.{{.Name}}, t.{{.Name}}, opt) {
Expand Down
6 changes: 6 additions & 0 deletions cmd/struct_equal_generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ func getFields(fields []Field, node *ast.StructType, imports map[string]string)
HasEqualOpt: res.HasEqualOpt,
IsArray: res.IsArray,
IsMap: res.IsMap,
MapKeyType: res.MapKeyType,
MapItemType: res.MapItemType,
}
if res.SubType != nil {
f.SubType = &Field{
Expand All @@ -312,6 +314,8 @@ func getFields(fields []Field, node *ast.StructType, imports map[string]string)
HasEqualOpt: res.SubType.HasEqualOpt,
IsArray: res.SubType.IsArray,
IsMap: res.SubType.IsMap,
// MapKeyType: res.MapKeyType,
// MapItemType: res.MapItemType,
}
}
fields = append(fields, f)
Expand All @@ -336,6 +340,8 @@ func getFields(fields []Field, node *ast.StructType, imports map[string]string)
HasString: res.HasStringer,
HasEqual: res.HasEqual,
HasEqualOpt: res.HasEqualOpt,
// MapKeyType: res.MapKeyType,
// MapItemType: res.MapItemType,
})
if res.Name == "Index" {
needsOptionsIndex = true
Expand Down
13 changes: 10 additions & 3 deletions cmd/struct_equal_generator/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type Field struct {
HasEqualOpt bool
IsArray bool
IsMap bool
MapKeyType string
MapItemType string
SubType *Field
}

Expand Down Expand Up @@ -120,6 +122,8 @@ type getTypeStringResponse struct {
HasEqualOpt bool
IsArray bool
IsMap bool
MapKeyType string
MapItemType string
StructType *ast.StructType
SubType *getTypeStringResponse
}
Expand Down Expand Up @@ -172,9 +176,12 @@ func getTypeString(expr ast.Expr, imports map[string]string) getTypeStringRespon
rKey := getTypeString(t.Key, imports)
rValue := getTypeString(t.Value, imports)
return getTypeStringResponse{
Name: "map[" + rKey.Name + "]" + rValue.Name,
IsComplex: rValue.IsComplex,
IsMap: true,
Name: "map[" + rKey.Name + "]" + rValue.Name,
MapKeyType: rKey.Name,
MapItemType: rValue.Name,
IsComplex: rValue.IsComplex,
IsMap: true,
IsComparable: isComparable(rValue.Name),
}
case *ast.SelectorExpr:
start := expr.Pos() - 1
Expand Down
42 changes: 42 additions & 0 deletions cmd/struct_equal_generator/utils.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ func CheckSameNilAndLen[T any](s,t []T, opts ...Options) bool {
return true
}

func CheckSameNilAndLenMap[S comparable, T any](s, t map[S]T, opts ...Options) bool {
opt := getOptions(opts...)

if !opt.NilSameAsEmpty {
if s == nil && t != nil {
return false
}
if t == nil && s != nil {
return false
}
}
if len(s) != len(t) {
return false
}
return true
}

func equalComparableSlice[T comparable](s1, s2 []T, opt Options) bool {
if !opt.NilSameAsEmpty {
if s1 == nil && s2 != nil {
Expand Down Expand Up @@ -94,3 +111,28 @@ func ValueOrNil[T any](v *T) any {
}
return *v
}

func equalMapStringMapSting(m1, m2 map[string]map[string]string, opt Options) bool {
if !opt.NilSameAsEmpty {
if m1 == nil && m2 != nil {
return false
}
if m2 == nil && m1 != nil {
return false
}
}

if len(m1) != len(m2) {
return false
}
for k1, v1 := range m1 {
if v2, ok := m2[k1]; !ok {
return false
} else {
if !equalComparableMap(v1, v2, opt){
return false
}
}
}
return true
}
42 changes: 42 additions & 0 deletions models/utils_compare.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9a0d8d5

Please sign in to comment.