Skip to content

Instantly share code, notes, and snippets.

@captncraig
Created May 8, 2014 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save captncraig/8643cd9c740fcb691a52 to your computer and use it in GitHub Desktop.
Save captncraig/8643cd9c740fcb691a52 to your computer and use it in GitHub Desktop.
Object Deconstructor
package objectPrinter
import (
"fmt"
"reflect"
)
func DeconstructThing(value interface{}, prefix string, m map[string]interface{}, depth int) {
key := prefix
//key will be used for all leaf nodes
if key == "" {
key = "value"
}
//handle nil up front
if value == nil {
m[key] = nil
return
}
var val reflect.Value
typ := reflect.TypeOf(value)
//If it is already Value (from recursive call) back up a level
if typ.Name() == "Value" && typ.PkgPath() == "reflect" {
val = value.(reflect.Value)
typ = val.Type()
} else {
val = reflect.ValueOf(value)
}
kind := typ.Kind()
//dereference pointers till we get a real thing
for kind == reflect.Ptr || kind == reflect.Interface {
val = val.Elem()
typ = val.Type()
kind = typ.Kind()
}
//limit depth for sanity
if depth > 5 {
return
}
switch kind {
//primative types are leaf nodes
case reflect.Bool,
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64:
m[key] = val.Int()
case reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64:
m[key] = val.Uint()
// reflect.Float32,
// reflect.Float64,
// reflect.Complex64,
// reflect.Complex128,
// reflect.Uintptr,
// reflect.UnsafePointer,
case reflect.String:
m[key] = val.String()
case reflect.Chan:
m[key] = typ.String()
case reflect.Struct:
n := val.NumField()
for i := 0; i < n; i++ {
name := typ.Field(i).Name
if prefix != "" {
prefix = prefix + "."
}
DeconstructThing(val.Field(i), prefix+name, m, depth+1)
}
case reflect.Slice, reflect.Array:
n := val.Len()
for i := 0; i < n; i++ {
DeconstructThing(val.Index(i), fmt.Sprintf("%v[%d]", prefix, i), m, depth)
}
//if all else fails, toString it
default:
m[key] = fmt.Sprintf("%v", value)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment