github.com/scottcagno/storage@v1.8.0/pkg/util/structs.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 func StructFields(m interface{}) (string, []reflect.StructField) { 9 typ := reflect.TypeOf(m) 10 if typ.Kind() == reflect.Ptr { 11 typ = typ.Elem() 12 } 13 if typ.Kind() != reflect.Struct { 14 fmt.Printf("%v type can't have attributes inspected\n", typ.Kind()) 15 return typ.Name(), nil 16 } 17 var sfl []reflect.StructField 18 for i := 0; i < typ.NumField(); i++ { 19 sf := typ.Field(i) 20 if !sf.Anonymous { 21 sfl = append(sfl, sf) 22 } 23 } 24 return typ.Name(), sfl 25 } 26 27 var ( 28 types = []reflect.Kind{ 29 reflect.Uint, 30 reflect.Uint8, 31 reflect.Uint16, 32 reflect.Uint32, 33 reflect.Uint64, 34 35 reflect.Int, 36 reflect.Int8, 37 reflect.Int16, 38 reflect.Int32, 39 reflect.Int64, 40 41 reflect.Float32, 42 reflect.Float64, 43 44 reflect.Complex64, 45 reflect.Complex128, 46 47 reflect.Bool, 48 reflect.Chan, 49 reflect.Func, 50 reflect.Interface, 51 reflect.Array, 52 reflect.Map, 53 reflect.Slice, 54 reflect.Struct, 55 56 reflect.String, 57 58 reflect.Ptr, 59 reflect.Uintptr, 60 reflect.UnsafePointer, 61 } 62 ) 63 64 func InspectStructV(val reflect.Value) { 65 if val.Kind() == reflect.Interface && !val.IsNil() { 66 elm := val.Elem() 67 if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { 68 val = elm 69 } 70 } 71 if val.Kind() == reflect.Ptr { 72 val = val.Elem() 73 } 74 75 for i := 0; i < val.NumField(); i++ { 76 valueField := val.Field(i) 77 typeField := val.Type().Field(i) 78 address := "not-addressable" 79 80 if valueField.Kind() == reflect.Interface && !valueField.IsNil() { 81 elm := valueField.Elem() 82 if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr { 83 valueField = elm 84 } 85 } 86 87 if valueField.Kind() == reflect.Ptr { 88 valueField = valueField.Elem() 89 90 } 91 if valueField.CanAddr() { 92 address = fmt.Sprintf("0x%X", valueField.Addr().Pointer()) 93 } 94 95 fmt.Printf("Field Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n", typeField.Name, 96 valueField.Interface(), address, typeField.Type, valueField.Kind()) 97 98 if valueField.Kind() == reflect.Struct { 99 InspectStructV(valueField) 100 } 101 } 102 } 103 104 func InspectStruct(v interface{}) { 105 InspectStructV(reflect.ValueOf(v)) 106 }