github.com/hedzr/evendeep@v0.4.8/diff/tool.go (about)

     1  package diff
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"unsafe"
     7  
     8  	"github.com/hedzr/evendeep/dbglog"
     9  	"github.com/hedzr/evendeep/internal/tool"
    10  )
    11  
    12  type visit struct {
    13  	al, ar unsafe.Pointer
    14  	typ    reflect.Type
    15  }
    16  
    17  type sliceIndex int
    18  
    19  func (n sliceIndex) String() string {
    20  	return fmt.Sprintf("[%d]", n)
    21  }
    22  
    23  type mapKey struct {
    24  	Key interface{}
    25  }
    26  
    27  func (n mapKey) String() string {
    28  	return fmt.Sprintf("[%#v]", n.Key)
    29  }
    30  
    31  type structField string
    32  
    33  func (n structField) String() string {
    34  	return fmt.Sprintf(".%s", string(n))
    35  }
    36  
    37  //
    38  
    39  // isEmptyObject detects the emptiness of a slice or a map
    40  func isEmptyObject(v reflect.Value) (yes bool) {
    41  	if kind := v.Kind(); !tool.KindIs(kind, reflect.Invalid, reflect.Slice, reflect.Map, reflect.Array) {
    42  		return
    43  	}
    44  	if yes = tool.IsZero(v); yes {
    45  		return
    46  	}
    47  	yes = v.Len() == 0
    48  	return
    49  }
    50  
    51  func isEmptyStruct(v reflect.Value) (yes bool) {
    52  	if kind := v.Kind(); kind != reflect.Struct {
    53  		return
    54  	}
    55  	yes = tool.IsZero(v)
    56  	return
    57  }
    58  
    59  func isEmptyStructDeeply(v reflect.Value) (yes bool) {
    60  	if kind := v.Kind(); kind != reflect.Struct {
    61  		return
    62  	}
    63  	ve := reflect.New(v.Type()).Elem()
    64  	inf := newInfo(WithTreatEmptyStructPtrAsNilPtr(true))
    65  	dbglog.Log(" isEmptyStructDeeply(v): %+v", tool.Valfmt(&v))
    66  	dbglog.Log("          the empty obj: %+v", tool.Valfmt(&ve))
    67  	yes = inf.diff(v, ve)
    68  	return
    69  }
    70  
    71  //
    72  
    73  //
    74  
    75  // func kindis(k reflect.Kind, kinds ...reflect.Kind) (yes bool) {
    76  // 	for _, kk := range kinds {
    77  // 		if yes = k == kk; yes {
    78  // 			break
    79  // 		}
    80  // 	}
    81  // 	return
    82  // }
    83  
    84  // func typfmtlite(v *reflect.Value) string {
    85  // 	// v := reflect.ValueOf(val)
    86  //
    87  // 	if v == nil || !v.IsValid() {
    88  // 		return "<invalid>"
    89  // 	}
    90  // 	t := v.Type()
    91  // 	return fmt.Sprintf("%v", t)
    92  // }
    93  //
    94  // func valfmtlite(val typ.Any) string {
    95  // 	v := reflect.ValueOf(val)
    96  // 	if !v.IsValid() {
    97  // 		return "<invalid>"
    98  // 	}
    99  // 	if v.Kind() == reflect.Bool {
   100  // 		if v.Bool() {
   101  // 			return "true"
   102  // 		}
   103  // 		return "false"
   104  // 	}
   105  // 	if tool.IsNil(v) {
   106  // 		return "<nil>"
   107  // 	}
   108  // 	if tool.IsZero(v) {
   109  // 		return "<zero>"
   110  // 	}
   111  // 	if v.Kind() == reflect.String {
   112  // 		return v.String()
   113  // 	}
   114  // 	if tool.HasStringer(&v) {
   115  // 		res := v.MethodByName("String").Call(nil)
   116  // 		return res[0].String()
   117  // 	}
   118  // 	if tool.IsNumericKind(v.Kind()) {
   119  // 		return fmt.Sprintf("%v", v.Interface())
   120  // 	}
   121  // 	if tool.CanConvert(&v, tool.StringType) {
   122  // 		return v.Convert(tool.StringType).String()
   123  // 	}
   124  // 	if v.CanInterface() {
   125  // 		return fmt.Sprintf("%v", v.Interface())
   126  // 	}
   127  // 	return fmt.Sprintf("<%v>", v.Kind())
   128  // }