You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.7 KiB
Go
159 lines
3.7 KiB
Go
1 year ago
|
package nreflect
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
// HasChild type check. eg: array, slice, map, struct
|
||
|
func HasChild(v reflect.Value) bool {
|
||
|
switch v.Kind() {
|
||
|
case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// IsArrayOrSlice check. eg: array, slice
|
||
|
func IsArrayOrSlice(k reflect.Kind) bool {
|
||
|
return k == reflect.Slice || k == reflect.Array
|
||
|
}
|
||
|
|
||
|
// IsSimpleKind kind in: string, bool, intX, uintX, floatX
|
||
|
func IsSimpleKind(k reflect.Kind) bool {
|
||
|
if reflect.String == k {
|
||
|
return true
|
||
|
}
|
||
|
return k > reflect.Invalid && k <= reflect.Float64
|
||
|
}
|
||
|
|
||
|
// IsAnyInt check is intX or uintX type
|
||
|
func IsAnyInt(k reflect.Kind) bool {
|
||
|
return k >= reflect.Int && k <= reflect.Uintptr
|
||
|
}
|
||
|
|
||
|
// IsIntx check is intX or uintX type
|
||
|
func IsIntx(k reflect.Kind) bool {
|
||
|
return k >= reflect.Int && k <= reflect.Int64
|
||
|
}
|
||
|
|
||
|
// IsUintX check is intX or uintX type
|
||
|
func IsUintX(k reflect.Kind) bool {
|
||
|
return k >= reflect.Uint && k <= reflect.Uintptr
|
||
|
}
|
||
|
|
||
|
// IsNil reflect value
|
||
|
func IsNil(v reflect.Value) bool {
|
||
|
switch v.Kind() {
|
||
|
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||
|
return v.IsNil()
|
||
|
default:
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// IsFunc value
|
||
|
func IsFunc(val any) bool {
|
||
|
if val == nil {
|
||
|
return false
|
||
|
}
|
||
|
return reflect.TypeOf(val).Kind() == reflect.Func
|
||
|
}
|
||
|
|
||
|
// IsEqual determines if two objects are considered equal.
|
||
|
//
|
||
|
// TIP: cannot compare function type
|
||
|
func IsEqual(src, dst any) bool {
|
||
|
if src == nil || dst == nil {
|
||
|
return src == dst
|
||
|
}
|
||
|
|
||
|
bs1, ok := src.([]byte)
|
||
|
if !ok {
|
||
|
return reflect.DeepEqual(src, dst)
|
||
|
}
|
||
|
|
||
|
bs2, ok := dst.([]byte)
|
||
|
if !ok {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if bs1 == nil || bs2 == nil {
|
||
|
return bs1 == nil && bs2 == nil
|
||
|
}
|
||
|
return bytes.Equal(bs1, bs2)
|
||
|
}
|
||
|
|
||
|
// IsEqualValues determines if two objects or two object-values are considered equal.
|
||
|
//
|
||
|
// TIP: cannot compare function type
|
||
|
func IsEqualValues(src, dst any) bool {
|
||
|
if IsEqual(src, dst) {
|
||
|
return true
|
||
|
}
|
||
|
dstType := reflect.TypeOf(dst)
|
||
|
if dstType == nil {
|
||
|
return false
|
||
|
}
|
||
|
srcValue := reflect.ValueOf(src)
|
||
|
if srcValue.IsValid() && srcValue.Type().ConvertibleTo(dstType) {
|
||
|
// Attempt comparison after type conversion
|
||
|
return reflect.DeepEqual(srcValue.Convert(dstType).Interface(), dst)
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// IsEmpty reflect value check
|
||
|
func IsEmpty(v reflect.Value) bool {
|
||
|
switch v.Kind() {
|
||
|
case reflect.Invalid:
|
||
|
return true
|
||
|
case reflect.String, reflect.Array:
|
||
|
return v.Len() == 0
|
||
|
case reflect.Map, reflect.Slice:
|
||
|
return v.Len() == 0 || v.IsNil()
|
||
|
case reflect.Bool:
|
||
|
return !v.Bool()
|
||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||
|
return v.Int() == 0
|
||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||
|
return v.Uint() == 0
|
||
|
case reflect.Float32, reflect.Float64:
|
||
|
return v.Float() == 0
|
||
|
case reflect.Interface, reflect.Ptr, reflect.Func:
|
||
|
return v.IsNil()
|
||
|
}
|
||
|
|
||
|
return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
|
||
|
}
|
||
|
|
||
|
// IsEmptyValue reflect value check.
|
||
|
// Difference the IsEmpty(), if value is ptr, will check real elem.
|
||
|
//
|
||
|
// From src/pkg/encoding/json/encode.go.
|
||
|
func IsEmptyValue(v reflect.Value) bool {
|
||
|
switch v.Kind() {
|
||
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||
|
return v.Len() == 0
|
||
|
case reflect.Bool:
|
||
|
return !v.Bool()
|
||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||
|
return v.Int() == 0
|
||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||
|
return v.Uint() == 0
|
||
|
case reflect.Float32, reflect.Float64:
|
||
|
return v.Float() == 0
|
||
|
case reflect.Interface, reflect.Ptr:
|
||
|
if v.IsNil() {
|
||
|
return true
|
||
|
}
|
||
|
return IsEmptyValue(v.Elem())
|
||
|
case reflect.Func:
|
||
|
return v.IsNil()
|
||
|
case reflect.Invalid:
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|