github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zreflect/utils.go (about)

     1  package zreflect
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	_ "unsafe"
     7  )
     8  
     9  const (
    10  	Tag            = "z"
    11  	ignoreTagValue = "-"
    12  	nameConnector  = "::"
    13  )
    14  
    15  func GetStructTag(field reflect.StructField, tags ...string) (tagValue, tagOpts string) {
    16  	if len(tags) > 0 {
    17  		for i := range tags {
    18  			tagValue = field.Tag.Get(tags[i])
    19  			if tagValue == ignoreTagValue {
    20  				return "", ""
    21  			}
    22  			if t, v := checkTagValidity(tagValue); t != "" {
    23  				return t, v
    24  			}
    25  		}
    26  	} else {
    27  		tagValue = field.Tag.Get(Tag)
    28  		if tagValue == ignoreTagValue {
    29  			return "", ""
    30  		}
    31  		if t, v := checkTagValidity(tagValue); t != "" {
    32  			return t, v
    33  		}
    34  
    35  		tagValue = field.Tag.Get("json")
    36  		if tagValue == ignoreTagValue {
    37  			return "", ""
    38  		}
    39  		if t, v := checkTagValidity(tagValue); t != "" {
    40  			return t, v
    41  		}
    42  	}
    43  
    44  	return field.Name, ""
    45  }
    46  
    47  func Nonzero(v reflect.Value) bool {
    48  	switch v.Kind() {
    49  	case reflect.Bool:
    50  		return v.Bool()
    51  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    52  		return v.Int() != 0
    53  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    54  		return v.Uint() != 0
    55  	case reflect.Float32, reflect.Float64:
    56  		return v.Float() != 0
    57  	case reflect.Complex64, reflect.Complex128:
    58  		return v.Complex() != complex(0, 0)
    59  	case reflect.String:
    60  		return v.String() != ""
    61  	case reflect.Struct:
    62  		for i := 0; i < v.NumField(); i++ {
    63  			if Nonzero(reflect.Indirect(v.Field(i))) {
    64  				return true
    65  			}
    66  		}
    67  		return false
    68  	case reflect.Array:
    69  		for i := 0; i < v.Len(); i++ {
    70  			if Nonzero(v.Index(i)) {
    71  				return true
    72  			}
    73  		}
    74  		return false
    75  	case reflect.Map, reflect.Interface, reflect.Slice, reflect.Ptr, reflect.Chan, reflect.Func:
    76  		return !v.IsNil()
    77  	case reflect.UnsafePointer:
    78  		return v.Pointer() != 0
    79  	}
    80  	return true
    81  }
    82  
    83  func CanExpand(t reflect.Type) bool {
    84  	switch t.Kind() {
    85  	case reflect.Map, reflect.Struct,
    86  		reflect.Interface, reflect.Array, reflect.Slice,
    87  		reflect.Ptr:
    88  		return true
    89  	}
    90  	return false
    91  }
    92  
    93  func CanInline(t reflect.Type) bool {
    94  	switch t.Kind() {
    95  	case reflect.Map:
    96  		return !CanExpand(t.Elem())
    97  	case reflect.Struct:
    98  		for i := 0; i < t.NumField(); i++ {
    99  			if CanExpand(t.Field(i).Type) {
   100  				return false
   101  			}
   102  		}
   103  		return true
   104  	case reflect.Interface:
   105  		return false
   106  	case reflect.Array, reflect.Slice:
   107  		return !CanExpand(t.Elem())
   108  	case reflect.Ptr:
   109  		return false
   110  	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
   111  		return false
   112  	}
   113  	return true
   114  }
   115  
   116  func IsLabel(t reflect.Type) bool {
   117  	switch t.Kind() {
   118  	case reflect.Interface, reflect.Struct:
   119  		return true
   120  	}
   121  	return false
   122  }
   123  
   124  func checkTagValidity(tagValue string) (tag, tagOpts string) {
   125  	if tagValue == "" {
   126  		return "", ""
   127  	}
   128  	valueSplit := strings.SplitN(tagValue, ",", 2)
   129  	if len(valueSplit) < 2 {
   130  		return valueSplit[0], ""
   131  	}
   132  	return valueSplit[0], valueSplit[1]
   133  }
   134  
   135  //go:linkname ifaceIndir reflect.ifaceIndir
   136  //go:noescape
   137  func ifaceIndir(Type) bool
   138  
   139  func GetAbbrKind(val reflect.Value) reflect.Kind {
   140  	kind := val.Kind()
   141  	switch {
   142  	case kind >= reflect.Int && kind <= reflect.Int64:
   143  		return reflect.Int
   144  	case kind >= reflect.Uint && kind <= reflect.Uint64:
   145  		return reflect.Uint
   146  	case kind >= reflect.Float32 && kind <= reflect.Float64:
   147  		return reflect.Float64
   148  	default:
   149  		return kind
   150  	}
   151  }