Select Git revision
map_params.go
map_params.go 1.51 KiB
package struct_utils
import (
"encoding/json"
"fmt"
"reflect"
"strings"
)
//convert fields in a struct to a map of parameters, as if defined in a URL
//we use this mainly for legacy functions that expect params to be defined in a map[string]string
//to convert the new params struct into such a map
func MapParams(data interface{}) map[string]string {
params := map[string]string{}
addStructParams(params, reflect.ValueOf(data))
return params
}
//recursive function
func addStructParams(params map[string]string, structValue reflect.Value) {
t := structValue.Type()
if t.Kind() != reflect.Struct {
return
}
for i := 0; i < t.NumField(); i++ {
tf := t.Field(i)
//recurse for embedded structs
if tf.Anonymous {
addStructParams(params, structValue.Field(i))
} else {
jsonTags := strings.Split(t.Field(i).Tag.Get("json"), ",")
skip := false
if jsonTags[0] == "-" || jsonTags[0] == "" {
skip = true
} else {
for _, option := range jsonTags[1:] {
if option == "omitempty" && structValue.Field(i).IsZero() { // ignore the field if omitempty is applicable
skip = true
}
}
}
if !skip {
//lists must be written as JSON lists so they can be unmarshalled
//jsut because that is how the legacy code did it
if t.Field(i).Type.Kind() == reflect.Slice {
jsonValue, _ := json.Marshal(structValue.Field(i).Interface())
params[jsonTags[0]] = string(jsonValue)
} else {
params[jsonTags[0]] = fmt.Sprintf("%v", structValue.Field(i).Interface())
}
}
}
}
}