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  }