ref: 02e50c0126d06aa72ff22ab462d2257fa655f116
parent: 42b302fc6b1cf4cf7b1d46073a0ce515f0ae9307
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Fri Mar 18 19:18:40 EDT 2016
Remove duplicate doArithmetic
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -1479,120 +1479,6 @@
// safeJS returns the given string as a html/template JS content.
func safeJS(a interface{}) template.JS { return template.JS(cast.ToString(a)) }-func doArithmetic(a, b interface{}, op rune) (interface{}, error) {- av := reflect.ValueOf(a)
- bv := reflect.ValueOf(b)
- var ai, bi int64
- var af, bf float64
- var au, bu uint64
- switch av.Kind() {- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- ai = av.Int()
- switch bv.Kind() {- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bi = bv.Int()
- case reflect.Float32, reflect.Float64:
- af = float64(ai) // may overflow
- ai = 0
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bu = bv.Uint()
- if ai >= 0 {- au = uint64(ai)
- ai = 0
- } else {- bi = int64(bu) // may overflow
- bu = 0
- }
- default:
- return nil, errors.New("Can't apply the operator to the values")- }
- case reflect.Float32, reflect.Float64:
- af = av.Float()
- switch bv.Kind() {- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bf = float64(bv.Int()) // may overflow
- case reflect.Float32, reflect.Float64:
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bf = float64(bv.Uint()) // may overflow
- default:
- return nil, errors.New("Can't apply the operator to the values")- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- au = av.Uint()
- switch bv.Kind() {- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- bi = bv.Int()
- if bi >= 0 {- bu = uint64(bi)
- bi = 0
- } else {- ai = int64(au) // may overflow
- au = 0
- }
- case reflect.Float32, reflect.Float64:
- af = float64(au) // may overflow
- au = 0
- bf = bv.Float()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- bu = bv.Uint()
- default:
- return nil, errors.New("Can't apply the operator to the values")- }
- case reflect.String:
- as := av.String()
- if bv.Kind() == reflect.String && op == '+' {- bs := bv.String()
- return as + bs, nil
- }
- return nil, errors.New("Can't apply the operator to the values")- default:
- return nil, errors.New("Can't apply the operator to the values")- }
-
- switch op {- case '+':
- if ai != 0 || bi != 0 {- return ai + bi, nil
- } else if af != 0 || bf != 0 {- return af + bf, nil
- } else if au != 0 || bu != 0 {- return au + bu, nil
- }
- return 0, nil
- case '-':
- if ai != 0 || bi != 0 {- return ai - bi, nil
- } else if af != 0 || bf != 0 {- return af - bf, nil
- } else if au != 0 || bu != 0 {- return au - bu, nil
- }
- return 0, nil
- case '*':
- if ai != 0 || bi != 0 {- return ai * bi, nil
- } else if af != 0 || bf != 0 {- return af * bf, nil
- } else if au != 0 || bu != 0 {- return au * bu, nil
- }
- return 0, nil
- case '/':
- if bi != 0 {- return ai / bi, nil
- } else if bf != 0 {- return af / bf, nil
- } else if bu != 0 {- return au / bu, nil
- }
- return nil, errors.New("Can't divide the value by 0")- default:
- return nil, errors.New("There is no such an operation")- }
-}
-
// mod returns a % b.
func mod(a, b interface{}) (int64, error) {av := reflect.ValueOf(a)
@@ -1745,7 +1631,7 @@
func init() { funcMap = template.FuncMap{ "absURL": func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) },- "add": func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '+') },+ "add": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '+') },"after": after,
"apply": apply,
"base64Decode": base64Decode,
@@ -1757,7 +1643,7 @@
"dateFormat": dateFormat,
"delimit": delimit,
"dict": dictionary,
- "div": func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '/') },+ "div": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '/') },"echoParam": returnWhenSet,
"emojify": emojify,
"eq": eq,
@@ -1785,7 +1671,7 @@
"md5": md5,
"mod": mod,
"modBool": modBool,
- "mul": func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '*') },+ "mul": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '*') },"ne": ne,
"partial": partial,
"pluralize": pluralize,
@@ -1810,7 +1696,7 @@
"sort": sortSeq,
"split": split,
"string": func(v interface{}) string { return cast.ToString(v) },- "sub": func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '-') },+ "sub": func(a, b interface{}) (interface{}, error) { return helpers.DoArithmetic(a, b, '-') },"substr": substr,
"title": func(a string) string { return strings.Title(a) },"trim": trim,
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -250,57 +250,6 @@
}
}
-func TestArethmic(t *testing.T) {- for i, this := range []struct {- a interface{}- b interface{}- op rune
- expect interface{}- }{- {1, 2, '+', int64(3)},- {1, 2, '-', int64(-1)},- {2, 2, '*', int64(4)},- {4, 2, '/', int64(2)},- {uint8(1), uint8(3), '+', uint64(4)},- {uint8(3), uint8(2), '-', uint64(1)},- {uint8(2), uint8(2), '*', uint64(4)},- {uint16(4), uint8(2), '/', uint64(2)},- {4, 2, '¤', false},- {4, 0, '/', false},- {float64(2.3), float64(2.3), '+', float64(4.6)},- {float64(2.3), int(2), '*', float64(4.6)},- {int(1), float64(2), '+', float64(3)},- {int(1), uint(2), '+', uint64(3)},- {1, "do", '+', false},- {float64(1), uint(2), '+', float64(3)},- {float64(1), "do", '+', false},- {uint(1), int(2), '+', uint64(3)},- {uint(1), int(-2), '+', int64(-1)},- {int(-1), uint(2), '+', int64(1)},- {uint(1), float64(2), '+', float64(3)},- {uint(1), "do", '+', false},- {"do ", "be", '+', "do be"},- {"do ", "be", '*', false},- {t, t, '+', false},- } {- // TODO(bep): Take precision into account.
- result, err := doArithmetic(this.a, this.b, this.op)
- if b, ok := this.expect.(bool); ok && !b {- if err == nil {- t.Errorf("[%d] doArethmic didn't return an expected error", i)- }
- } else {- if err != nil {- t.Errorf("[%d] failed: %s", i, err)- continue
- }
- if !reflect.DeepEqual(result, this.expect) {- t.Errorf("[%d] doArethmic got %v (%T) but expected %v (%T)", i, result, result, this.expect, this.expect)- }
- }
- }
-}
-
func TestMod(t *testing.T) { for i, this := range []struct { a interface{}--
⑨