diff --git a/tpl/collections/collections.go b/tpl/collections/collections.go index ae2d73b46b4..ab3d08f5e11 100644 --- a/tpl/collections/collections.go +++ b/tpl/collections/collections.go @@ -254,24 +254,9 @@ func (ns *Namespace) In(l interface{}, v interface{}) bool { if vv.Type() == lvv.Type() && vv.String() == lvv.String() { return true } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - switch vv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if vv.Int() == lvv.Int() { - return true - } - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - switch vv.Kind() { - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if vv.Uint() == lvv.Uint() { - return true - } - } - case reflect.Float32, reflect.Float64: - switch vv.Kind() { - case reflect.Float32, reflect.Float64: - if vv.Float() == lvv.Float() { + default: + if isNumber(vv.Kind()) && isNumber(lvv.Kind()) { + if numberToFloat(vv) == numberToFloat(lvv) { return true } } diff --git a/tpl/collections/collections_test.go b/tpl/collections/collections_test.go index 64c358ddd12..ea23a1de773 100644 --- a/tpl/collections/collections_test.go +++ b/tpl/collections/collections_test.go @@ -244,10 +244,13 @@ func TestIn(t *testing.T) { {[]int{1, 2, 4}, 3, false}, {[]float64{1.23, 2.45, 4.67}, 1.23, true}, {[]float64{1.234567, 2.45, 4.67}, 1.234568, false}, + {[]float64{1, 2, 3}, 1, true}, + {[]float32{1, 2, 3}, 1, true}, {"this substring should be found", "substring", true}, {"this substring should not be found", "subseastring", false}, {nil, "foo", false}, } { + errMsg := fmt.Sprintf("[%d] %v", i, test) result := ns.In(test.l1, test.l2) diff --git a/tpl/collections/reflect_helpers.go b/tpl/collections/reflect_helpers.go new file mode 100644 index 00000000000..f07ea978c5f --- /dev/null +++ b/tpl/collections/reflect_helpers.go @@ -0,0 +1,64 @@ +// Copyright 2017 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collections + +import ( + "reflect" +) + +func numberToFloat(v reflect.Value) float64 { + switch kind := v.Kind(); { + case isFloat(kind): + return v.Float() + case isInt(kind): + return float64(v.Int()) + case isUInt(kind): + return float64(v.Uint()) + case kind == reflect.Interface: + return numberToFloat(v.Elem()) + default: + panic("Invalid type in numberToFloat") + } +} + +func isNumber(kind reflect.Kind) bool { + return isInt(kind) || isUInt(kind) || isFloat(kind) +} + +func isInt(kind reflect.Kind) bool { + switch kind { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return true + default: + return false + } +} + +func isUInt(kind reflect.Kind) bool { + switch kind { + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return true + default: + return false + } +} + +func isFloat(kind reflect.Kind) bool { + switch kind { + case reflect.Float32, reflect.Float64: + return true + default: + return false + } +} diff --git a/tpl/collections/where.go b/tpl/collections/where.go index e9528fb867b..d8045b301e9 100644 --- a/tpl/collections/where.go +++ b/tpl/collections/where.go @@ -381,7 +381,7 @@ func (ns *Namespace) checkWhereMap(seqv, kv, mv reflect.Value, path []string, op return rv.Interface(), nil } -// toFloat returns the int value if possible. +// toFloat returns the float value if possible. func toFloat(v reflect.Value) (float64, error) { switch v.Kind() { case reflect.Float32, reflect.Float64: @@ -393,6 +393,7 @@ func toFloat(v reflect.Value) (float64, error) { } // toInt returns the int value if possible, -1 if not. +// TODO(bep) consolidate all these reflect funcs. func toInt(v reflect.Value) (int64, error) { switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: