1
0
mirror of https://github.com/danog/liquid.git synced 2024-11-30 08:39:01 +01:00
liquid/generics/compare.go

103 lines
2.4 KiB
Go
Raw Normal View History

2017-06-27 16:28:39 +02:00
package generics
import (
"reflect"
)
2017-06-28 15:36:39 +02:00
var (
int64Type = reflect.TypeOf(int64(0))
float64Type = reflect.TypeOf(float64(0))
)
2017-06-27 16:28:39 +02:00
// Equal returns a bool indicating whether a == b after conversion.
2017-07-02 05:52:23 +02:00
func Equal(a, b interface{}) bool { // nolint: gocyclo
2017-06-28 04:54:27 +02:00
if a == nil || b == nil {
return a == b
}
2017-06-28 15:36:39 +02:00
ra, rb := reflect.ValueOf(a), reflect.ValueOf(b)
switch joinKind(ra.Kind(), rb.Kind()) {
case reflect.Array, reflect.Slice:
if ra.Len() != rb.Len() {
return false
}
for i := 0; i < ra.Len(); i++ {
if !Equal(ra.Index(i).Interface(), rb.Index(i).Interface()) {
return false
}
}
return true
case reflect.Bool:
return ra.Bool() == rb.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return ra.Convert(int64Type).Int() == rb.Convert(int64Type).Int()
case reflect.Float32, reflect.Float64:
return ra.Convert(float64Type).Float() == rb.Convert(float64Type).Float()
case reflect.String:
return ra.String() == rb.String()
default:
return a == b
}
2017-06-27 16:28:39 +02:00
}
// Less returns a bool indicating whether a < b.
func Less(a, b interface{}) bool {
2017-06-28 15:36:39 +02:00
if a == nil || b == nil {
2017-06-28 03:30:47 +02:00
return false
}
2017-06-28 15:36:39 +02:00
ra, rb := reflect.ValueOf(a), reflect.ValueOf(b)
switch joinKind(ra.Kind(), rb.Kind()) {
2017-06-28 03:30:47 +02:00
case reflect.Bool:
2017-06-28 15:36:39 +02:00
return !ra.Bool() && rb.Bool()
2017-06-27 16:28:39 +02:00
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2017-06-28 15:36:39 +02:00
return ra.Convert(int64Type).Int() < rb.Convert(int64Type).Int()
2017-06-27 16:28:39 +02:00
case reflect.Float32, reflect.Float64:
2017-06-28 15:36:39 +02:00
return ra.Convert(float64Type).Float() < rb.Convert(float64Type).Float()
2017-06-27 16:28:39 +02:00
case reflect.String:
2017-06-28 15:36:39 +02:00
return ra.String() < rb.String()
2017-06-27 16:28:39 +02:00
default:
2017-06-28 15:36:39 +02:00
return false
2017-06-27 16:28:39 +02:00
}
}
2017-07-02 05:52:23 +02:00
func joinKind(a, b reflect.Kind) reflect.Kind { // nolint: gocyclo
2017-06-28 15:36:39 +02:00
if a == b {
return a
2017-06-27 23:29:50 +02:00
}
2017-06-28 15:36:39 +02:00
switch a {
case reflect.Array, reflect.Slice:
if b == reflect.Array || b == reflect.Slice {
return reflect.Slice
2017-06-27 16:28:39 +02:00
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2017-06-28 15:36:39 +02:00
if isIntKind(b) {
return reflect.Int64
2017-06-27 16:28:39 +02:00
}
2017-06-28 15:36:39 +02:00
if isFloatKind(b) {
return reflect.Float64
2017-06-27 16:28:39 +02:00
}
case reflect.Float32, reflect.Float64:
2017-06-28 15:36:39 +02:00
if isIntKind(b) || isFloatKind(b) {
return reflect.Float64
2017-06-27 16:28:39 +02:00
}
}
2017-06-28 15:36:39 +02:00
return reflect.Invalid
2017-06-27 16:28:39 +02:00
}
2017-06-28 15:36:39 +02:00
func isIntKind(k reflect.Kind) bool {
switch k {
2017-06-27 16:28:39 +02:00
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return true
default:
return false
}
}
2017-06-28 15:36:39 +02:00
func isFloatKind(k reflect.Kind) bool {
switch k {
2017-06-27 16:28:39 +02:00
case reflect.Float32, reflect.Float64:
return true
default:
return false
}
}