diff --git a/utils/reflect.go b/utils/reflect.go index ce56db60b..23f589f54 100644 --- a/utils/reflect.go +++ b/utils/reflect.go @@ -19,6 +19,7 @@ along with this program. If not, see package utils import ( + "errors" "fmt" "reflect" "strconv" @@ -121,3 +122,34 @@ func AsMapStringIface(item interface{}) (map[string]interface{}, error) { } return out, nil } + +// GreaterThan attempts to compare two items +// returns the result or error if not comparable +func GreaterThan(item, oItem interface{}, orEqual bool) (gte bool, err error) { + typItem := reflect.TypeOf(item) + typOItem := reflect.TypeOf(oItem) + fmt.Println(typItem.Comparable(), + typOItem.Comparable(), + typItem, + typOItem, + typItem == typOItem) + if !typItem.Comparable() || + !typOItem.Comparable() || + typItem != typOItem { + return false, errors.New("incomparable") + } + if orEqual && reflect.DeepEqual(item, oItem) { + return true, nil + } + valItm := reflect.ValueOf(item) + valOItm := reflect.ValueOf(oItem) + switch typItem.Kind() { + case reflect.Float32, reflect.Float64: + gte = valItm.Float() > valOItm.Float() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + gte = valItm.Int() > valOItm.Int() + default: // unsupported comparison + err = fmt.Errorf("unsupported type: %v", typItem) + } + return +} diff --git a/utils/reflect_test.go b/utils/reflect_test.go index 2d527dfbe..87afbd99f 100644 --- a/utils/reflect_test.go +++ b/utils/reflect_test.go @@ -20,6 +20,7 @@ package utils import ( "reflect" "testing" + "time" ) func TestReflectFieldAsStringOnStruct(t *testing.T) { @@ -138,3 +139,45 @@ func TestReflectAsMapStringIface(t *testing.T) { t.Errorf("Expecting: %+v, received: %+v", expectOutMp, outMp) } } + +func TestGreaterThan(t *testing.T) { + if _, err := GreaterThan(1, 1.2, false); err == nil || err.Error() != "incomparable" { + t.Error(err) + } + if _, err := GreaterThan(struct{}{}, + map[string]interface{}{"a": "a"}, false); err == nil || err.Error() != "incomparable" { + t.Error(err) + } + if gte, err := GreaterThan(1.2, 1.2, true); err != nil { + t.Error(err) + } else if !gte { + t.Error("should be equal") + } + if gte, err := GreaterThan(1.3, 1.2, false); err != nil { + t.Error(err) + } else if !gte { + t.Error("should be greater than") + } + if gte, err := GreaterThan(1.2, 1.3, false); err != nil { + t.Error(err) + } else if gte { + t.Error("should be greater than") + } + if gte, err := GreaterThan(2, 1, false); err != nil { + t.Error(err) + } else if !gte { + t.Error("should be greater than") + } + if gte, err := GreaterThan(time.Duration(2*time.Second), + time.Duration(1*time.Second), false); err != nil { + t.Error(err) + } else if !gte { + t.Error("should be greater than") + } + if gte, err := GreaterThan(time.Duration(1*time.Second), + time.Duration(2*time.Second), false); err != nil { + t.Error(err) + } else if gte { + t.Error("should be less than") + } +}