gitlab.com/evatix-go/core@v1.3.55/coredata/coredynamic/reflectGetUsingReflectValue.go (about) 1 package coredynamic 2 3 import ( 4 "reflect" 5 "unsafe" 6 7 "gitlab.com/evatix-go/core/constants" 8 "gitlab.com/evatix-go/core/errcore" 9 "gitlab.com/evatix-go/core/internal/reflectinternal" 10 ) 11 12 type reflectGetUsingReflectValue struct{} 13 14 // PublicValuesMapStruct 15 // 16 // returns structs fields map[string]Interface{} 17 // map[string:fieldName]Interface{}:PublicValue 18 // 19 // Only public values will be collected into map values 20 func (it reflectGetUsingReflectValue) PublicValuesMapStruct(structValue reflect.Value) ( 21 map[string]interface{}, error, 22 ) { 23 if structValue.Kind() != reflect.Struct { 24 return nil, errcore.Expected.ReflectButFound( 25 reflect.Struct, 26 structValue.Kind()) 27 } 28 29 structType := structValue.Type() 30 structNumFields := structType.NumField() 31 fieldToValueMap := make(map[string]interface{}, structNumFields) 32 33 for i := 0; i < structNumFields; i++ { 34 fieldStruct := structType.Field(i) 35 36 // ignore unexported fields 37 if fieldStruct.PkgPath != "" { 38 continue 39 } 40 41 field := structValue.Field(i) 42 fieldToValueMap[fieldStruct.Name] = field.Interface() 43 } 44 45 return fieldToValueMap, nil 46 } 47 48 // FieldNameWithTypeMap 49 // 50 // returns structs fields map[string]Interface{} 51 // map[string:fieldName]reflect.Type:fieldType 52 // 53 // Only public values will be collected into map values 54 func (it reflectGetUsingReflectValue) FieldNameWithTypeMap( 55 rv reflect.Value, 56 ) map[string]reflect.Type { 57 structValue := rv 58 structValueKind := structValue.Kind() 59 60 for structValueKind == reflect.Ptr || structValueKind == reflect.Interface { 61 // mutating dangerous code 62 structValue = structValue.Elem() 63 structValueKind = structValue.Kind() 64 } 65 66 if !structValue.IsValid() || structValueKind != reflect.Struct { 67 return nil 68 } 69 70 structType := structValue.Type() 71 fieldsLength := structType.NumField() 72 fieldsHashset := 73 make( 74 map[string]reflect.Type, 75 fieldsLength) 76 77 var name string 78 79 for i := 0; i < fieldsLength; i++ { 80 field := structType.Field(i) 81 name = field.Name 82 fieldsHashset[name] = field.Type 83 } 84 85 return fieldsHashset 86 } 87 88 // FieldNameWithValuesMap 89 // 90 // returns structs all fields (public, private) map[string]Interface{} 91 // map[string:fieldName]interface{}:fieldValuePublicOrPrivate 92 // 93 // unlike PublicValuesMapStruct to map it collects 94 // all fields with values including the private ones. 95 // 96 // However, this one will be slower in performance than PublicValuesMapStruct. 97 func (it reflectGetUsingReflectValue) FieldNameWithValuesMap( 98 structValue reflect.Value, 99 ) ( 100 map[string]interface{}, error, 101 ) { 102 structType := structValue.Type() 103 structNumFields := structType.NumField() 104 fieldToValueMap := make(map[string]interface{}, structNumFields) 105 106 // structValue is not addressable, create a temporary copy 107 if !structValue.CanAddr() { 108 newType := reflect.New(structType).Elem() 109 newType.Set(structValue) 110 // structValue is now addressable 111 structValue = newType 112 } 113 114 for i := 0; i < structNumFields; i++ { 115 fieldType := structType.Field(i) 116 fieldValue := structValue.Field(i) 117 118 if fieldType.PkgPath != "" { 119 unexportedField := reflect.NewAt( 120 fieldType.Type, 121 unsafe.Pointer(fieldValue.UnsafeAddr())).Elem() 122 fieldToValueMap[fieldType.Name] = unexportedField.Interface() 123 } else { 124 fieldToValueMap[fieldType.Name] = fieldValue.Interface() 125 } 126 } 127 128 return fieldToValueMap, nil 129 } 130 131 // FieldNamesMap 132 // 133 // returns structs fields map[string]bool 134 // map[string:fieldName]bool 135 func (it reflectGetUsingReflectValue) FieldNamesMap( 136 rv reflect.Value, 137 ) (map[string]bool, error) { 138 structValue := rv 139 structValueKind := structValue.Kind() 140 141 for structValueKind == reflect.Ptr || structValueKind == reflect.Interface { 142 // mutating dangerous code 143 structValue = structValue.Elem() 144 structValueKind = structValue.Kind() 145 } 146 147 if !structValue.IsValid() || structValueKind != reflect.Struct { 148 return map[string]bool{}, 149 errcore.Expected.ReflectButFound( 150 reflect.Struct, structValueKind) 151 } 152 153 structType := structValue.Type() 154 fieldsLength := structType.NumField() 155 fieldsMap := make( 156 map[string]bool, 157 fieldsLength+1) 158 159 for i := 0; i < fieldsLength; i++ { 160 name := structType.Field(i).Name 161 fieldsMap[name] = true 162 } 163 164 return fieldsMap, nil 165 } 166 167 // StructFieldsMap 168 // 169 // returns structs all fields (public, private) map[string]reflect.StructField 170 // map[string:fieldName]reflect.StructField:StructField 171 func (it reflectGetUsingReflectValue) StructFieldsMap( 172 rv reflect.Value, 173 ) map[string]reflect.StructField { 174 structValue := rv 175 structValueKind := structValue.Kind() 176 177 for structValueKind == reflect.Ptr || structValueKind == reflect.Interface { 178 // mutating dangerous code 179 structValue = structValue.Elem() 180 structValueKind = structValue.Kind() 181 } 182 183 if !structValue.IsValid() || structValueKind != reflect.Struct { 184 return nil 185 } 186 187 structType := structValue.Type() 188 fieldsLength := structType.NumField() 189 fieldsHashset := 190 make( 191 map[string]reflect.StructField, 192 fieldsLength) 193 194 var name string 195 196 for i := 0; i < fieldsLength; i++ { 197 field := structType.Field(i) 198 name = field.Name 199 fieldsHashset[name] = field 200 } 201 202 return fieldsHashset 203 } 204 205 // NullFieldsMap 206 // 207 // returns structs all fields (public, private) map[string]bool 208 // null fields map only 209 func (it reflectGetUsingReflectValue) NullFieldsMap( 210 level int, 211 reflectVal reflect.Value, 212 ) map[string]bool { 213 structType := reflectVal.Type() 214 structValueKind := reflectVal.Kind() 215 hasLevel := level > constants.InvalidIndex 216 structValue := reflectVal 217 218 // reducing ****ToValue to ToValue 219 for structValueKind == reflect.Ptr || structValueKind == reflect.Interface { 220 // mutating dangerous code 221 structValue = structValue.Elem() 222 structValueKind = structValue.Kind() 223 224 level-- 225 if hasLevel && level <= 0 { 226 break 227 } 228 } 229 230 if !structValue.IsValid() || structValueKind != reflect.Struct { 231 return map[string]bool{} 232 } 233 234 structNumFields := structType.NumField() 235 hashset := make( 236 map[string]bool, 237 structNumFields+1) 238 var fieldValue reflect.Value 239 var fieldType reflect.StructField 240 241 for i := 0; i < structNumFields; i++ { 242 fieldValue = structValue.Field(i) 243 244 if reflectinternal.IsNullUsingReflectValue(fieldValue) { 245 fieldType = structType.Field(i) 246 hashset[fieldType.Name] = true 247 } 248 } 249 250 return hashset 251 } 252 253 // NullOrZeroFieldsMap 254 // 255 // returns structs all fields (public, private) map[string]bool 256 // null or zero fields map only 257 func (it reflectGetUsingReflectValue) NullOrZeroFieldsMap( 258 level int, 259 reflectVal reflect.Value, 260 ) map[string]bool { 261 structType := reflectVal.Type() 262 structValueKind := reflectVal.Kind() 263 hasLevel := level > constants.InvalidIndex 264 structValue := reflectVal 265 266 // reducing ****ToValue to ToValue 267 for structValueKind == reflect.Ptr || structValueKind == reflect.Interface { 268 // mutating dangerous code 269 structValue = structValue.Elem() 270 structValueKind = structValue.Kind() 271 272 level-- 273 if hasLevel && level <= 0 { 274 break 275 } 276 } 277 278 if !structValue.IsValid() || structValueKind != reflect.Struct { 279 return map[string]bool{} 280 } 281 282 structNumFields := structType.NumField() 283 hashset := make( 284 map[string]bool, 285 structNumFields+1) 286 var fieldValue reflect.Value 287 var fieldType reflect.StructField 288 289 for i := 0; i < structNumFields; i++ { 290 fieldValue = structValue.Field(i) 291 292 if reflectinternal.IsZeroReflectValue(fieldValue) { 293 fieldType = structType.Field(i) 294 hashset[fieldType.Name] = true 295 } 296 } 297 298 return hashset 299 }