update getNested utility to better handle slice fields

This commit is contained in:
parent cd20d2c9eb
commit 551d06fbe0
Signed by: tablet
GPG Key ID: 924A5F6AF051E87C

33
util.go

@ -54,19 +54,40 @@ func coerceInt(input reflect.Value, dst reflect.Value) interface{} {
var arrRegex, _ = regexp.Compile(`\[(?P<index>\d+)]$`)
func getNested(field string, value reflect.Value) (*reflect.StructField, *reflect.Value, error) {
func getNested(field string, aValue reflect.Value) (*reflect.Type, *reflect.Value, error) {
if strings.HasPrefix(field, ".") || strings.HasSuffix(field, ".") {
return nil, nil, fmt.Errorf("Malformed field name %s passed", field)
return nil, nil, fmt.Errorf(errFmtMalformedField, field)
}
dots := strings.Split(field, ".")
if value.Kind() != reflect.Struct && arrRegex.FindString(dots[0]) == "" {
return nil, nil, fmt.Errorf("This value is not a struct!")
if value.Kind() != reflect.Struct /*&& arrRegex.FindString(dots[0]) == ""*/ {
if value.Kind() == reflect.Slice {
st := reflect.MakeSlice(value.Type().Elem(), 0, 0)
for i := 0; i < value.Len(); i++ {
cur := value.Index(i)
if len(dots) > 1 {
_, cv, _ := getNested(strings.Join(dots[1:], "."), cur.FieldByName(dots[0]))
reflect.Append(st, *cv)
//return getNested(, "."), fv)
} else {
reflect.Append(st, cur)
}
}
typ := st.Type().Elem()
return &typ, &st, nil
}
if len(dots) > 1 {
return nil, nil, ErrNotSliceOrStruct
} else {
return &aft, &value, nil
}
/*ft := value.Type()
*/
}
ref := value
if ref.Kind() == reflect.Pointer {
ref = ref.Elem()
}
var fv reflect.Value = ref.FieldByName(arrRegex.ReplaceAllString(dots[0], ""))
var fv = ref.FieldByName(arrRegex.ReplaceAllString(dots[0], ""))
if arrRegex.FindString(dots[0]) != "" && fv.Kind() == reflect.Slice {
matches := arrRegex.FindStringSubmatch(dots[0])
ridx, _ := strconv.Atoi(matches[0])
@ -78,7 +99,7 @@ func getNested(field string, value reflect.Value) (*reflect.StructField, *reflec
if len(dots) > 1 {
return getNested(strings.Join(dots[1:], "."), fv)
} else {
return &ft, &fv, nil
return &ft.Type, &fv, nil
}
}
func makeSettable(rval reflect.Value, value interface{}) reflect.Value {