diff --git a/struct_utils/named_values_to_struct.go b/struct_utils/named_values_to_struct.go index b8f21428d27458b6e07102d5c0be664478ff6b20..055591bd9da9d9b7be4253d6b470287110b10430 100644 --- a/struct_utils/named_values_to_struct.go +++ b/struct_utils/named_values_to_struct.go @@ -52,7 +52,6 @@ func NamedValuesFromReader(prefix string, reader string_utils.KeyReader) map[str logger.Debugf("Key(%s) undefined", key) continue } - logger.Debugf("key(%s)=\"%s\"", key, value) result[strings.ToLower(key)] = []string{value} //split only if valid CSV between [...] @@ -224,14 +223,24 @@ func unmarshalNamedValuesIntoStructPtr(prefix string, namedValues map[string][]s } } - //recurse into anonymous sub-structs - if structTypeField.Type.Kind() == reflect.Struct { - if nameList, err := unmarshalNamedValuesIntoStructPtr(fieldName, namedValues, structTypeField.Type, structPtrValue.Elem().Field(i).Addr()); err != nil { - return nil, errors.Wrapf(err, "failed on %s.%s", structType.Name(), fieldName) - } else { - usedNameList = append(usedNameList, nameList...) + //if type can scan/unmarshal, do not recurse into its fields + //because we do not want to iterate over fields inside structs like time.Time + //that implements their own parsers + { + fieldPtr := structPtrValue.Elem().Field(i).Addr().Interface() + _, ok1 := fieldPtr.(sql.Scanner) + _, ok2 := fieldPtr.(json.Unmarshaler) + if !ok1 && !ok2 { + //recurse into sub-structs + if structTypeField.Type.Kind() == reflect.Struct { + if nameList, err := unmarshalNamedValuesIntoStructPtr(fieldName, namedValues, structTypeField.Type, structPtrValue.Elem().Field(i).Addr()); err != nil { + return nil, errors.Wrapf(err, "failed on %s.%s", structType.Name(), fieldName) + } else { + usedNameList = append(usedNameList, nameList...) + } + continue + } } - continue } fieldValues, ok := namedValues[fieldName] @@ -244,6 +253,7 @@ func unmarshalNamedValuesIntoStructPtr(prefix string, namedValues map[string][]s continue //field has no value specified in URL, do not remove values not defined (cannot clear defined struct fields with named values) } structPtrFieldValue := structPtrValue.Elem().Field(i) + if structPtrFieldValue.Kind() == reflect.Ptr { //this is a ptr, allocate a new value and set it //then we can dereference to set it below