@@ -52,6 +52,7 @@ var hashEqualsType = reflect.TypeOf((*base.HashEquals)(nil)).Elem()
52
52
func genHash64EqualsForLogicalOps (x any ) ([]byte , error ) {
53
53
c := new (cc )
54
54
vType := reflect .TypeOf (x )
55
+ // for Hash64 function.
55
56
c .write ("// Hash64 implements the Hash64Equals interface." )
56
57
c .write ("func (op *%v) Hash64(h base.Hasher) {" , vType .Name ())
57
58
c .write ("h.HashString(%v)" , logicalOpName2PlanCodecString (vType .Name ()))
@@ -72,6 +73,23 @@ func genHash64EqualsForLogicalOps(x any) ([]byte, error) {
72
73
}
73
74
}
74
75
c .write ("}" )
76
+ // for Equals function.
77
+ c .write ("// Equals implements the Hash64Equals interface, only receive *%v pointer." , vType .Name ())
78
+ c .write ("func (op *%v) Equals(other any) bool {" , vType .Name ())
79
+ c .write ("if other == nil { return false }" )
80
+ c .write ("op2, ok := other.(*%v)" , vType .Name ())
81
+ c .write ("if !ok { return false }" )
82
+ for i := 0 ; i < vType .NumField (); i ++ {
83
+ f := vType .Field (i )
84
+ if ! isHash64EqualsField (f ) {
85
+ continue
86
+ }
87
+ leftCallName := "op." + vType .Field (i ).Name
88
+ rightCallName := "op2." + vType .Field (i ).Name
89
+ c .EqualsElement (f .Type , leftCallName , rightCallName )
90
+ }
91
+ c .write ("return true" )
92
+ c .write ("}" )
75
93
return c .format ()
76
94
}
77
95
@@ -88,6 +106,30 @@ func isHash64EqualsField(fType reflect.StructField) bool {
88
106
return fType .Tag .Get ("hash64-equals" ) == "true"
89
107
}
90
108
109
+ // EqualsElement EqualsElements generate the equals function for every field inside logical op.
110
+ func (c * cc ) EqualsElement (fType reflect.Type , lhs , rhs string ) {
111
+ switch fType .Kind () {
112
+ case reflect .Slice :
113
+ c .write ("if len(%v) != len(%v) { return false }" , lhs , rhs )
114
+ c .write ("for i, one := range %v {" , lhs )
115
+ // one more round
116
+ c .EqualsElement (fType .Elem (), "one" , rhs + "[i]" )
117
+ c .write ("}" )
118
+ case reflect .String , reflect .Bool , reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 ,
119
+ reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Float32 , reflect .Float64 :
120
+ c .write ("if %v != %v {return false}" , lhs , rhs )
121
+ default :
122
+ if fType .Implements (hashEqualsType ) {
123
+ if fType .Kind () == reflect .Struct {
124
+ rhs = "&" + rhs
125
+ }
126
+ c .write ("if !%v.Equals(%v) {return false}" , lhs , rhs )
127
+ } else {
128
+ panic ("doesn't support element type" + fType .Kind ().String ())
129
+ }
130
+ }
131
+ }
132
+
91
133
func (c * cc ) Hash64Element (fType reflect.Type , callName string ) {
92
134
switch fType .Kind () {
93
135
case reflect .Slice :
0 commit comments