Skip to content

Instantly share code, notes, and snippets.

@sarathsp06
Created October 30, 2015 12:53
Show Gist options
  • Save sarathsp06/fece35d7d98bf331c70b to your computer and use it in GitHub Desktop.
Save sarathsp06/fece35d7d98bf331c70b to your computer and use it in GitHub Desktop.
A function to converta a striuct to map of string to interface
package main
import (
"fmt"
"reflect"
)
//StructToMap converts a struct to map of string to interface
//Its uses the tag 'map' to check the name to be used
//if the value is nil no key is added
func StructToMap(in interface{}) (m map[string]interface{}, err error) {
m = make(map[string]interface{})
v := reflect.ValueOf(in)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
// we only accept structs
if v.Kind() != reflect.Struct {
err = fmt.Errorf("only accepts structs; got %T", v)
return
}
tp := v.Type()
for i := 0; i < tp.NumField(); i++ {
// gets us a StructField
field := tp.Field(i)
value := v.Field(i)
if !isEmptyValue(value) {
if tagv := field.Tag.Get("map"); tagv != "" {
m[tagv] = v.Field(i).Interface()
} else {
m[field.Name] = v.Field(i).Interface()
}
}
}
return
}
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
}
return false
}
type Thenga int
type Foo struct {
Number Thenga `map:"whatever"`
IsActive *bool `map:"is_active"`
}
func main() {
f1 := Foo{}
f2 := Foo{Number: Thenga(0)}
isActive := false
f3 := Foo{Number: Thenga(1), IsActive: &isActive}
f4 := Foo{IsActive: &isActive}
g1, _ := StructToMap(f1)
g2, _ := StructToMap(f2)
g3, _ := StructToMap(f3)
g4, _ := StructToMap(f4)
fmt.Printf("%+v\n", g1)
fmt.Printf("%+v\n", g2)
fmt.Printf("%+v\n", g3)
fmt.Printf("%+v\n", g4)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment