From 2fdda76882a17bd27c6f36b4b6a445ec46197af7 Mon Sep 17 00:00:00 2001 From: letu <282130106@qq.com> Date: Thu, 13 May 2021 16:16:02 +0800 Subject: [PATCH] add template functions eq,lt to support uint and int compare. --- server/web/templatefunc.go | 86 ++++++++++++++++++++------------- server/web/templatefunc_test.go | 20 ++++++++ 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/server/web/templatefunc.go b/server/web/templatefunc.go index 53c99018..f83fc572 100644 --- a/server/web/templatefunc.go +++ b/server/web/templatefunc.go @@ -607,25 +607,34 @@ func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) { if err != nil { return false, err } - if k1 != k2 { - return false, errBadComparison - } truth := false - switch k1 { - case boolKind: - truth = v1.Bool() == v2.Bool() - case complexKind: - truth = v1.Complex() == v2.Complex() - case floatKind: - truth = v1.Float() == v2.Float() - case intKind: - truth = v1.Int() == v2.Int() - case stringKind: - truth = v1.String() == v2.String() - case uintKind: - truth = v1.Uint() == v2.Uint() - default: - panic("invalid kind") + if k1 != k2 { + // Special case: Can compare integer values regardless of type's sign. + switch { + case k1 == intKind && k2 == uintKind: + truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() + case k1 == uintKind && k2 == intKind: + truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) + default: + return false, errBadComparison + } + } else { + switch k1 { + case boolKind: + truth = v1.Bool() == v2.Bool() + case complexKind: + truth = v1.Complex() == v2.Complex() + case floatKind: + truth = v1.Float() == v2.Float() + case intKind: + truth = v1.Int() == v2.Int() + case stringKind: + truth = v1.String() == v2.String() + case uintKind: + truth = v1.Uint() == v2.Uint() + default: + panic("invalid kind") + } } if truth { return true, nil @@ -653,23 +662,32 @@ func lt(arg1, arg2 interface{}) (bool, error) { if err != nil { return false, err } - if k1 != k2 { - return false, errBadComparison - } truth := false - switch k1 { - case boolKind, complexKind: - return false, errBadComparisonType - case floatKind: - truth = v1.Float() < v2.Float() - case intKind: - truth = v1.Int() < v2.Int() - case stringKind: - truth = v1.String() < v2.String() - case uintKind: - truth = v1.Uint() < v2.Uint() - default: - panic("invalid kind") + if k1 != k2 { + // Special case: Can compare integer values regardless of type's sign. + switch { + case k1 == intKind && k2 == uintKind: + truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() + case k1 == uintKind && k2 == intKind: + truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int()) + default: + return false, errBadComparison + } + } else { + switch k1 { + case boolKind, complexKind: + return false, errBadComparisonType + case floatKind: + truth = v1.Float() < v2.Float() + case intKind: + truth = v1.Int() < v2.Int() + case stringKind: + truth = v1.String() < v2.String() + case uintKind: + truth = v1.Uint() < v2.Uint() + default: + panic("invalid kind") + } } return truth, nil } diff --git a/server/web/templatefunc_test.go b/server/web/templatefunc_test.go index df5cfa40..0c6f17f7 100644 --- a/server/web/templatefunc_test.go +++ b/server/web/templatefunc_test.go @@ -378,3 +378,23 @@ func TestMapGet(t *testing.T) { t.Errorf("Error happens %v", err) } } + +func Test_eq(t *testing.T) { + var a uint = 1 + var b int32 = 1 + if res, err := eq(a, b); err != nil { + if !res { + t.Error("uint(1) and int32(1) should not be eq") + } + } +} + +func Test_lt(t *testing.T) { + var a uint = 1 + var b int32 = 2 + if res, err := lt(a, b); err != nil { + if !res { + t.Error("uint(1) not lt int32(2)") + } + } +}