github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/x/reflectx/reflectx.go (about)

     1  package reflectx
     2  
     3  import (
     4  	"bytes"
     5  	"reflect"
     6  )
     7  
     8  func Indirect(v reflect.Value) reflect.Value {
     9  	if v.Kind() == reflect.Ptr {
    10  		return Indirect(v.Elem())
    11  	}
    12  	return v
    13  }
    14  
    15  // New a `reflect.Value` with reflect.Type
    16  func New(t reflect.Type) reflect.Value {
    17  	v := reflect.New(t).Elem()
    18  	if t.Kind() == reflect.Ptr {
    19  		v.Set(New(t.Elem()).Addr())
    20  	}
    21  	return v
    22  }
    23  
    24  func IsEmptyValue(v interface{}) bool {
    25  	rv, ok := v.(reflect.Value)
    26  	if !ok {
    27  		rv = reflect.ValueOf(&v).Elem()
    28  	}
    29  	if rv.Kind() == reflect.Ptr && rv.IsNil() {
    30  		return true
    31  	}
    32  	if rv.Kind() == reflect.Interface && rv.IsNil() {
    33  		return true
    34  	}
    35  	if rv.Kind() == reflect.Invalid {
    36  		return true
    37  	}
    38  
    39  	if rv.IsValid() && rv.CanInterface() {
    40  		if chk, ok := rv.Interface().(interface{ IsZero() bool }); ok {
    41  			return chk.IsZero()
    42  		}
    43  	}
    44  	switch rv.Kind() {
    45  	case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
    46  		return rv.Len() == 0
    47  	case reflect.Bool:
    48  		return !rv.Bool()
    49  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    50  		return rv.Int() == 0
    51  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
    52  		return rv.Uint() == 0
    53  	case reflect.Float32, reflect.Float64:
    54  		return rv.Float() == 0
    55  	case reflect.Ptr, reflect.Interface:
    56  		return IsEmptyValue(rv.Elem())
    57  	}
    58  	return false
    59  }
    60  
    61  func TypeName(rt reflect.Type) string {
    62  	buf := bytes.NewBuffer(nil)
    63  	for rt.Kind() == reflect.Ptr {
    64  		buf.WriteByte('*')
    65  		rt = rt.Elem()
    66  	}
    67  	if pkg := rt.PkgPath(); pkg != "" {
    68  		buf.WriteString(pkg)
    69  		buf.WriteByte('.')
    70  	}
    71  	if name := rt.Name(); name != "" {
    72  		buf.WriteString(name)
    73  	}
    74  	buf.WriteString(rt.String())
    75  	return buf.String()
    76  }
    77  
    78  func DeRef(t reflect.Type) reflect.Type {
    79  	for t.Kind() == reflect.Ptr {
    80  		t = t.Elem()
    81  	}
    82  	return t
    83  }
    84  
    85  // NatureType return the v's nature type, for example:
    86  // Foo nature type is Foo
    87  // *Foo nature type is Foo
    88  // ***Foo nature type is Foo
    89  // reflect.TypeOf(Foo) nature type is Foo
    90  // (interface{})(Foo) nature type is Foo
    91  func NatureType(v interface{}) (rt reflect.Type) {
    92  	if !reflect.ValueOf(v).IsValid() {
    93  		return reflect.TypeOf(nil)
    94  	}
    95  
    96  	rt = reflect.TypeOf(v)
    97  	if t, ok := v.(reflect.Type); ok {
    98  		rt = t
    99  	}
   100  
   101  	kind := rt.Kind()
   102  	for kind == reflect.Ptr {
   103  		rt = rt.Elem()
   104  		kind = rt.Kind()
   105  	}
   106  
   107  	if kind == reflect.Interface {
   108  		return NatureType(reflect.New(rt).Elem().Interface())
   109  	}
   110  	return rt
   111  }
   112  
   113  func IsBytes(v interface{}) bool {
   114  	if _, ok := v.([]byte); ok {
   115  		return true
   116  	}
   117  	t := BasicAssertReflectType(v)
   118  	return IsBytesType(t)
   119  }
   120  
   121  func IsBytesType(t reflect.Type) bool {
   122  	return t.Kind() == reflect.Slice &&
   123  		t.Elem().Kind() == reflect.Uint8 &&
   124  		t.Elem().PkgPath() == ""
   125  }
   126  
   127  func BasicAssertReflectType(v interface{}) reflect.Type {
   128  	var t reflect.Type
   129  	switch x := v.(type) {
   130  	case reflect.Type:
   131  		t = x
   132  	case interface{ Type() reflect.Type }:
   133  		t = x.Type()
   134  	default:
   135  		t = reflect.TypeOf(v)
   136  	}
   137  	return t
   138  }