@@ -36,93 +36,186 @@ type Value struct {
36
36
37
37
// Equals returns true iff the two values are equal.
38
38
func (v Value ) Equals (rhs Value ) bool {
39
- return ! v .Less (rhs ) && ! rhs .Less (v )
39
+ if v .FloatValue != nil || rhs .FloatValue != nil {
40
+ var lf float64
41
+ if v .FloatValue != nil {
42
+ lf = float64 (* v .FloatValue )
43
+ } else if v .IntValue != nil {
44
+ lf = float64 (* v .IntValue )
45
+ } else {
46
+ return false
47
+ }
48
+ var rf float64
49
+ if rhs .FloatValue != nil {
50
+ rf = float64 (* rhs .FloatValue )
51
+ } else if rhs .IntValue != nil {
52
+ rf = float64 (* rhs .IntValue )
53
+ } else {
54
+ return false
55
+ }
56
+ return lf == rf
57
+ }
58
+ if v .IntValue != nil {
59
+ if rhs .IntValue != nil {
60
+ return * v .IntValue == * rhs .IntValue
61
+ }
62
+ return false
63
+ }
64
+ if v .StringValue != nil {
65
+ if rhs .StringValue != nil {
66
+ return * v .StringValue == * rhs .StringValue
67
+ }
68
+ return false
69
+ }
70
+ if v .BooleanValue != nil {
71
+ if rhs .BooleanValue != nil {
72
+ return * v .BooleanValue == * rhs .BooleanValue
73
+ }
74
+ return false
75
+ }
76
+ if v .ListValue != nil {
77
+ if rhs .ListValue != nil {
78
+ return v .ListValue .Equals (rhs .ListValue )
79
+ }
80
+ return false
81
+ }
82
+ if v .MapValue != nil {
83
+ if rhs .MapValue != nil {
84
+ return v .MapValue .Equals (rhs .MapValue )
85
+ }
86
+ return false
87
+ }
88
+ if v .Null {
89
+ if rhs .Null {
90
+ return true
91
+ }
92
+ return false
93
+ }
94
+ // No field is set, on either objects.
95
+ return true
40
96
}
41
97
42
98
// Less provides a total ordering for Value (so that they can be sorted, even
43
99
// if they are of different types).
44
100
func (v Value ) Less (rhs Value ) bool {
101
+ return v .Compare (rhs ) == - 1
102
+ }
103
+
104
+ // Compare provides a total ordering for Value (so that they can be
105
+ // sorted, even if they are of different types). The result will be 0 if
106
+ // v==rhs, -1 if v < rhs, and +1 if v > rhs.
107
+ func (v Value ) Compare (rhs Value ) int {
45
108
if v .FloatValue != nil {
46
109
if rhs .FloatValue == nil {
47
110
// Extra: compare floats and ints numerically.
48
111
if rhs .IntValue != nil {
49
- return float64 ( * v .FloatValue ) < float64 ( * rhs .IntValue )
112
+ return v .FloatValue . Compare ( Float ( * rhs .IntValue ) )
50
113
}
51
- return true
114
+ return - 1
52
115
}
53
- return * v .FloatValue < * rhs .FloatValue
116
+ return v .FloatValue . Compare ( * rhs .FloatValue )
54
117
} else if rhs .FloatValue != nil {
55
118
// Extra: compare floats and ints numerically.
56
119
if v .IntValue != nil {
57
- return float64 (* v .IntValue ) < float64 (* rhs .FloatValue )
120
+ return Float (* v .IntValue ). Compare (* rhs .FloatValue )
58
121
}
59
- return false
122
+ return 1
60
123
}
61
124
62
125
if v .IntValue != nil {
63
126
if rhs .IntValue == nil {
64
- return true
127
+ return - 1
65
128
}
66
- return * v .IntValue < * rhs .IntValue
129
+ return v .IntValue . Compare ( * rhs .IntValue )
67
130
} else if rhs .IntValue != nil {
68
- return false
131
+ return 1
69
132
}
70
133
71
134
if v .StringValue != nil {
72
135
if rhs .StringValue == nil {
73
- return true
136
+ return - 1
74
137
}
75
- return * v .StringValue < * rhs .StringValue
138
+ return strings . Compare ( string ( * v .StringValue ), string ( * rhs .StringValue ))
76
139
} else if rhs .StringValue != nil {
77
- return false
140
+ return 1
78
141
}
79
142
80
143
if v .BooleanValue != nil {
81
144
if rhs .BooleanValue == nil {
82
- return true
145
+ return - 1
83
146
}
84
- if * v .BooleanValue == * rhs .BooleanValue {
85
- return false
86
- }
87
- return * v .BooleanValue == false
147
+ return v .BooleanValue .Compare (* rhs .BooleanValue )
88
148
} else if rhs .BooleanValue != nil {
89
- return false
149
+ return 1
90
150
}
91
151
92
152
if v .ListValue != nil {
93
153
if rhs .ListValue == nil {
94
- return true
154
+ return - 1
95
155
}
96
- return v .ListValue .Less (rhs .ListValue )
156
+ return v .ListValue .Compare (rhs .ListValue )
97
157
} else if rhs .ListValue != nil {
98
- return false
158
+ return 1
99
159
}
100
160
if v .MapValue != nil {
101
161
if rhs .MapValue == nil {
102
- return true
162
+ return - 1
103
163
}
104
- return v .MapValue .Less (rhs .MapValue )
164
+ return v .MapValue .Compare (rhs .MapValue )
105
165
} else if rhs .MapValue != nil {
106
- return false
166
+ return 1
107
167
}
108
168
if v .Null {
109
169
if ! rhs .Null {
110
- return true
170
+ return - 1
111
171
}
112
- return false
172
+ return 0
113
173
} else if rhs .Null {
114
- return false
174
+ return 1
115
175
}
116
176
117
177
// Invalid Value-- nothing is set.
118
- return false
178
+ return 0
119
179
}
120
180
121
181
type Int int64
122
182
type Float float64
123
183
type String string
124
184
type Boolean bool
125
185
186
+ // Compare compares integers. The result will be 0 if i==rhs, -1 if i <
187
+ // rhs, and +1 if i > rhs.
188
+ func (i Int ) Compare (rhs Int ) int {
189
+ if i > rhs {
190
+ return 1
191
+ } else if i < rhs {
192
+ return - 1
193
+ }
194
+ return 0
195
+ }
196
+
197
+ // Compare compares floats. The result will be 0 if f==rhs, -1 if f <
198
+ // rhs, and +1 if f > rhs.
199
+ func (f Float ) Compare (rhs Float ) int {
200
+ if f > rhs {
201
+ return 1
202
+ } else if f < rhs {
203
+ return - 1
204
+ }
205
+ return 0
206
+ }
207
+
208
+ // Compare compares booleans. The result will be 0 if b==rhs, -1 if b <
209
+ // rhs, and +1 if b > rhs.
210
+ func (b Boolean ) Compare (rhs Boolean ) int {
211
+ if b == rhs {
212
+ return 0
213
+ } else if b == false {
214
+ return - 1
215
+ }
216
+ return 1
217
+ }
218
+
126
219
// Field is an individual key-value pair.
127
220
type Field struct {
128
221
Name string
@@ -134,29 +227,44 @@ type List struct {
134
227
Items []Value
135
228
}
136
229
230
+ // Equals compares two lists lexically.
231
+ func (l * List ) Equals (rhs * List ) bool {
232
+ if len (l .Items ) != len (rhs .Items ) {
233
+ return false
234
+ }
235
+
236
+ for i , lv := range l .Items {
237
+ if ! lv .Equals (rhs .Items [i ]) {
238
+ return false
239
+ }
240
+ }
241
+ return true
242
+ }
243
+
137
244
// Less compares two lists lexically.
138
245
func (l * List ) Less (rhs * List ) bool {
246
+ return l .Compare (rhs ) == - 1
247
+ }
248
+
249
+ // Compare compares two lists lexically. The result will be 0 if l==rhs, -1
250
+ // if l < rhs, and +1 if l > rhs.
251
+ func (l * List ) Compare (rhs * List ) int {
139
252
i := 0
140
253
for {
141
254
if i >= len (l .Items ) && i >= len (rhs .Items ) {
142
255
// Lists are the same length and all items are equal.
143
- return false
256
+ return 0
144
257
}
145
258
if i >= len (l .Items ) {
146
259
// LHS is shorter.
147
- return true
260
+ return - 1
148
261
}
149
262
if i >= len (rhs .Items ) {
150
263
// RHS is shorter.
151
- return false
264
+ return 1
152
265
}
153
- if l .Items [i ].Less (rhs .Items [i ]) {
154
- // LHS is less; return
155
- return true
156
- }
157
- if rhs .Items [i ].Less (l .Items [i ]) {
158
- // RHS is less; return
159
- return false
266
+ if c := l .Items [i ].Compare (rhs .Items [i ]); c != 0 {
267
+ return c
160
268
}
161
269
// The items are equal; continue.
162
270
i ++
@@ -191,8 +299,30 @@ func (m *Map) computeOrder() []int {
191
299
return m .order
192
300
}
193
301
302
+ // Equals compares two maps lexically.
303
+ func (m * Map ) Equals (rhs * Map ) bool {
304
+ if len (m .Items ) != len (rhs .Items ) {
305
+ return false
306
+ }
307
+ for _ , lfield := range m .Items {
308
+ rfield , ok := rhs .Get (lfield .Name )
309
+ if ! ok {
310
+ return false
311
+ }
312
+ if ! lfield .Value .Equals (rfield .Value ) {
313
+ return false
314
+ }
315
+ }
316
+ return true
317
+ }
318
+
194
319
// Less compares two maps lexically.
195
320
func (m * Map ) Less (rhs * Map ) bool {
321
+ return m .Compare (rhs ) == - 1
322
+ }
323
+
324
+ // Compare compares two maps lexically.
325
+ func (m * Map ) Compare (rhs * Map ) int {
196
326
var noAllocL , noAllocR [2 ]int
197
327
var morder , rorder []int
198
328
@@ -238,28 +368,22 @@ func (m *Map) Less(rhs *Map) bool {
238
368
for {
239
369
if i >= len (morder ) && i >= len (rorder ) {
240
370
// Maps are the same length and all items are equal.
241
- return false
371
+ return 0
242
372
}
243
373
if i >= len (morder ) {
244
374
// LHS is shorter.
245
- return true
375
+ return - 1
246
376
}
247
377
if i >= len (rorder ) {
248
378
// RHS is shorter.
249
- return false
379
+ return 1
250
380
}
251
381
fa , fb := & m.Items [morder [i ]], & rhs.Items [rorder [i ]]
252
- if fa .Name != fb .Name {
253
- // the map having the field name that sorts lexically less is "less"
254
- return fa .Name < fb .Name
382
+ if c := strings .Compare (fa .Name , fb .Name ); c != 0 {
383
+ return c
255
384
}
256
- if fa .Value .Less (fb .Value ) {
257
- // LHS is less; return
258
- return true
259
- }
260
- if fb .Value .Less (fa .Value ) {
261
- // RHS is less; return
262
- return false
385
+ if c := fa .Value .Compare (fb .Value ); c != 0 {
386
+ return c
263
387
}
264
388
// The items are equal; continue.
265
389
i ++
0 commit comments