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  }