github.com/hedzr/evendeep@v0.4.8/internal/tool/tool.go (about) 1 package tool 2 3 // tool.go - tools functions here 4 5 import ( 6 "fmt" 7 "log" 8 "reflect" 9 "strings" 10 "unsafe" 11 12 "github.com/hedzr/evendeep/dbglog" 13 "github.com/hedzr/evendeep/typ" 14 ) 15 16 func PtrOf(tgt reflect.Value) reflect.Value { 17 ret := reflect.NewAt(tgt.Type(), unsafe.Pointer(tgt.UnsafeAddr())) 18 return ret 19 } 20 21 // func ptr(tgt reflect.Value, want reflect.Type) (r reflect.Value) { 22 // //return reflect.PtrTo(tgt) 23 // //for tgt.Kind() != reflect.Ptr { 24 // //Log("tgt: %v, get pointer", tgt.Kind()) 25 // //r = reflect.NewAt(tgt.Type(), unsafe.Pointer(tgt.Pointer())) 26 // //} 27 // if tgt.CanAddr() { 28 // r = tgt.Addr() 29 // } else { 30 // // in hard way 31 // if tgt.IsNil() { 32 // tmp := reflect.New(want) 33 // tgt.Set(tmp) 34 // r = tmp 35 // } else { 36 // var v = tgt.Interface() 37 // Log(" v: %v", v) 38 // r = reflect.ValueOf(&v) 39 // Log(" ret: %v, *%v", r.Kind(), r.Elem().Kind()) 40 // } 41 // } 42 // if r.Type() == want { 43 // Log("ret: %v, *%v", r.Kind(), r.Elem().Kind()) 44 // return 45 // } 46 // 47 // Log("NOTE an temp pointer was created as *%v", want.Kind()) 48 // return reflect.New(want) 49 // } 50 51 func testFieldValue(valueField reflect.Value) (v reflect.Value, addrStr string) { 52 addrStr = "not-addressable" 53 if valueField.Kind() == reflect.Interface && !valueField.IsNil() { 54 elm := valueField.Elem() 55 if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { 56 valueField = elm 57 } 58 } 59 if valueField.Kind() == reflect.Ptr { 60 valueField = valueField.Elem() 61 } 62 if valueField.CanAddr() { 63 addrStr = fmt.Sprintf("0x%X", valueField.Addr().Pointer()) 64 } 65 v = valueField 66 return 67 } 68 69 func inspectStructV(val reflect.Value, level int) { 70 if val.Kind() == reflect.Interface && !val.IsNil() { 71 elm := val.Elem() 72 if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { 73 val = elm 74 } 75 } 76 if val.Kind() == reflect.Ptr { 77 val = val.Elem() 78 } 79 80 padding := strings.Repeat(" ", level) 81 for i, count := 0, val.NumField(); i < count; i++ { 82 valField := val.Field(i) 83 typeField := val.Type().Field(i) 84 valueField, address := testFieldValue(valField) 85 86 var v typ.Any 87 if valueField.IsValid() && !IsZero(valueField) && valueField.CanInterface() { 88 v = valueField.Interface() 89 } 90 log.Printf("%s%d/%d. Field Name: %s, Field Value: %v,\t Address: %v, Field type: %v [%s]\n", 91 padding, i, count, typeField.Name, v, address, typeField.Type, valueField.Kind()) 92 93 if valueField.Kind() == reflect.Struct { 94 inspectStructV(valueField, level+1) 95 } 96 } 97 } 98 99 // InspectStruct dumps wach field in a struct with its reflect information. 100 func InspectStruct(v typ.Any) { 101 inspectStructV(reflect.ValueOf(v), 0) 102 } 103 104 // MinInt returns min-value of a and b. 105 func MinInt(a, b int) int { 106 if a < b { 107 return a 108 } 109 return b 110 } 111 112 // Contains checks if name is in names. 113 func Contains(names []string, name string) bool { 114 for _, n := range names { 115 if strings.EqualFold(n, name) { 116 return true 117 } 118 } 119 return false 120 } 121 122 // ContainsPartialsOnly checks if testedString has a part of in partialNames list. 123 func ContainsPartialsOnly(partialNames []string, testedString string) (contains bool) { 124 for _, n := range partialNames { 125 if strings.Contains(testedString, n) { 126 return true 127 } 128 } 129 return 130 } 131 132 // PartialContainsShort checks if one of names has partialNeedle as a part. 133 func PartialContainsShort(names []string, partialNeedle string) (contains bool) { 134 for _, n := range names { 135 if strings.Contains(n, partialNeedle) { 136 return true 137 } 138 } 139 return 140 } 141 142 // PartialContains checks if one of names has partialNeedle as a part. 143 func PartialContains(names []string, partialNeedle string) (index int, matched string, contains bool) { 144 for ix, n := range names { 145 if strings.Contains(n, partialNeedle) { 146 return ix, n, true 147 } 148 } 149 return -1, "", false 150 } 151 152 // ReverseAnySlice reverse any slice/array. 153 func ReverseAnySlice(s typ.Any) { 154 n := reflect.ValueOf(s).Len() 155 swap := reflect.Swapper(s) 156 for i, j := 0, n-1; i < j; i, j = i+1, j-1 { 157 swap(i, j) 158 } 159 } 160 161 // FindInSlice finds a value elv is in array ns. 162 func FindInSlice(ns reflect.Value, elv typ.Any, i int) (found bool) { 163 for j := 0; j < ns.Len(); j++ { 164 tev := ns.Index(j).Interface() 165 // dbglog.Log(" testing tgt[%v](%v) and src[%v](%v)", j, tev, i, elv) 166 if reflect.DeepEqual(tev, elv) { 167 found = true 168 dbglog.Log("found an exists el at tgt[%v], for src[%v], value is: %v", j, i, elv) 169 break 170 } 171 } 172 return 173 } 174 175 // EqualClassical tests lhs and rhs is equal. 176 func EqualClassical(lhs, rhs reflect.Value) bool { 177 lv, rv := lhs.IsValid(), rhs.IsValid() 178 if !lv { 179 return !rv 180 } 181 if !rv { 182 return !lv 183 } 184 185 return reflect.DeepEqual(lhs.Interface(), rhs.Interface()) 186 }