Skip to content

Commit d12cf5a

Browse files
committed
tpl/collections: Fix In function for JSON arrays
Fixes #1468
1 parent e10e51a commit d12cf5a

File tree

4 files changed

+72
-19
lines changed

4 files changed

+72
-19
lines changed

‎tpl/collections/collections.go‎

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -254,24 +254,9 @@ func (ns *Namespace) In(l interface{}, v interface{}) bool {
254254
if vv.Type() == lvv.Type() && vv.String() == lvv.String() {
255255
return true
256256
}
257-
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
258-
switch vv.Kind() {
259-
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
260-
if vv.Int() == lvv.Int() {
261-
return true
262-
}
263-
}
264-
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
265-
switch vv.Kind() {
266-
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
267-
if vv.Uint() == lvv.Uint() {
268-
return true
269-
}
270-
}
271-
case reflect.Float32, reflect.Float64:
272-
switch vv.Kind() {
273-
case reflect.Float32, reflect.Float64:
274-
if vv.Float() == lvv.Float() {
257+
default:
258+
if isNumber(vv.Kind()) && isNumber(lvv.Kind()) {
259+
if numberToFloat(vv) == numberToFloat(lvv) {
275260
return true
276261
}
277262
}

‎tpl/collections/collections_test.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,13 @@ func TestIn(t *testing.T) {
244244
{[]int{1, 2, 4}, 3, false},
245245
{[]float64{1.23, 2.45, 4.67}, 1.23, true},
246246
{[]float64{1.234567, 2.45, 4.67}, 1.234568, false},
247+
{[]float64{1, 2, 3}, 1, true},
248+
{[]float32{1, 2, 3}, 1, true},
247249
{"this substring should be found", "substring", true},
248250
{"this substring should not be found", "subseastring", false},
249251
{nil, "foo", false},
250252
} {
253+
251254
errMsg := fmt.Sprintf("[%d] %v", i, test)
252255

253256
result := ns.In(test.l1, test.l2)

‎tpl/collections/reflect_helpers.go‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2017 The Hugo Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package collections
15+
16+
import (
17+
"reflect"
18+
)
19+
20+
func numberToFloat(v reflect.Value) float64 {
21+
switch kind := v.Kind(); {
22+
case isFloat(kind):
23+
return v.Float()
24+
case isInt(kind):
25+
return float64(v.Int())
26+
case isUInt(kind):
27+
return float64(v.Uint())
28+
case kind == reflect.Interface:
29+
return numberToFloat(v.Elem())
30+
default:
31+
panic("Invalid type in numberToFloat")
32+
}
33+
}
34+
35+
func isNumber(kind reflect.Kind) bool {
36+
return isInt(kind) || isUInt(kind) || isFloat(kind)
37+
}
38+
39+
func isInt(kind reflect.Kind) bool {
40+
switch kind {
41+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
42+
return true
43+
default:
44+
return false
45+
}
46+
}
47+
48+
func isUInt(kind reflect.Kind) bool {
49+
switch kind {
50+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
51+
return true
52+
default:
53+
return false
54+
}
55+
}
56+
57+
func isFloat(kind reflect.Kind) bool {
58+
switch kind {
59+
case reflect.Float32, reflect.Float64:
60+
return true
61+
default:
62+
return false
63+
}
64+
}

‎tpl/collections/where.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func (ns *Namespace) checkWhereMap(seqv, kv, mv reflect.Value, path []string, op
381381
return rv.Interface(), nil
382382
}
383383

384-
// toFloat returns the int value if possible.
384+
// toFloat returns the float value if possible.
385385
func toFloat(v reflect.Value) (float64, error) {
386386
switch v.Kind() {
387387
case reflect.Float32, reflect.Float64:
@@ -393,6 +393,7 @@ func toFloat(v reflect.Value) (float64, error) {
393393
}
394394

395395
// toInt returns the int value if possible, -1 if not.
396+
// TODO(bep) consolidate all these reflect funcs.
396397
func toInt(v reflect.Value) (int64, error) {
397398
switch v.Kind() {
398399
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:

0 commit comments

Comments
 (0)