github.com/best4tires/kit@v1.0.5/reflex/compare.go (about) 1 package reflex 2 3 import ( 4 "fmt" 5 "reflect" 6 "strings" 7 8 "golang.org/x/exp/constraints" 9 ) 10 11 func ZeroOf[T any]() T { 12 var t T 13 return t 14 } 15 16 func TypeOf[T any]() reflect.Type { 17 var t T 18 return reflect.TypeOf(t) 19 } 20 21 // CanConvert checks if v can be converted to T 22 func CanConvert[T any](v any) bool { 23 rv := reflect.ValueOf(v) 24 rty := TypeOf[T]() 25 return rv.CanConvert(rty) 26 } 27 28 // Convert converts v to to T. Convert Panics if convert fails 29 func Convert[T any](v any) T { 30 return reflect.ValueOf(v).Convert(TypeOf[T]()).Interface().(T) 31 } 32 33 func Compare[T constraints.Ordered](t1, t2 T) int { 34 switch { 35 case t1 < t2: 36 return -1 37 case t1 > t2: 38 return 1 39 default: 40 return 0 41 } 42 } 43 44 func compareBool(b1, b2 bool) int { 45 switch { 46 case !b1 && b2: 47 return -1 48 case b1 && !b2: 49 return 1 50 default: 51 return 0 52 } 53 } 54 55 // Compare compares to any-values and returns: 56 // strings.Compare of type-kind-names, if types of v1 and v2 are not equal 57 // 0: if values are equal; -1: if v1 < v2; 1: if v1 > v2 58 func CompareAny(v1, v2 any) int { 59 ty1 := baseKind(v1) 60 ty2 := baseKind(v2) 61 if ty1 != ty2 { 62 return strings.Compare(ty1.String(), ty2.String()) 63 } 64 switch ty1 { 65 case reflect.Bool: 66 return compareBool(Convert[bool](v1), Convert[bool](v2)) 67 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 68 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 69 return Compare(Convert[int](v1), Convert[int](v2)) 70 case reflect.Float32, reflect.Float64: 71 return Compare(Convert[float64](v1), Convert[float64](v2)) 72 default: 73 return strings.Compare(fmt.Sprintf("%v", v1), fmt.Sprintf("%v", v2)) 74 } 75 }