Reflect GreaterThan comparison

This commit is contained in:
DanB
2017-10-13 13:51:18 +02:00
parent e688dcd3e4
commit 2d6d968076
2 changed files with 75 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
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
}

View File

@@ -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")
}
}