Created
May 8, 2014 13:55
-
-
Save captncraig/8643cd9c740fcb691a52 to your computer and use it in GitHub Desktop.
Object Deconstructor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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