PromucFlow_constructor/app/server/utils/utils.go

57 lines
1.4 KiB
Go

package utils
import (
"fmt"
"reflect"
)
// ConvertMapToStruct converts a given map into a struct object
func ConvertMapToStruct(obj interface{}, objTags interface{}, m map[string]interface{}) error {
tags, _ := getTags(objTags)
for key, value := range m {
err := setField(obj, tags, key, value)
if err != nil {
return err
}
}
return nil
}
func setField(obj interface{}, tags map[string]string, name string, value interface{}) error {
// If the value is nil, then simply proceed without setting the value in the struct
if value == nil {
return nil
}
structValue := reflect.ValueOf(obj).Elem()
structFieldName := structValue.FieldByName(tags[name])
if !structFieldName.IsValid() {
return fmt.Errorf("No such field: %s in obj", name)
}
if !structFieldName.CanSet() {
return fmt.Errorf("Cannot set field: %s in obj", name)
}
structFieldType := structFieldName.Type()
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return fmt.Errorf("Provided value type doesn't match obj field type")
}
structFieldName.Set(val)
return nil
}
// getTags stores all the tags of the struct in a map along with the name of the field
func getTags(obj interface{}) (tags map[string]string, err error) {
tags = make(map[string]string)
objType := reflect.TypeOf(obj)
for i := 0; i < objType.NumField(); i++ {
field := objType.Field(i)
tag := field.Tag.Get("sql")
tags[tag] = field.Name
}
return tags, nil
}