(name string, data interface{}, val reflect.Value)
| 1076 | } |
| 1077 | |
| 1078 | func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { |
| 1079 | dataVal := reflect.Indirect(reflect.ValueOf(data)) |
| 1080 | dataValKind := dataVal.Kind() |
| 1081 | valType := val.Type() |
| 1082 | valElemType := valType.Elem() |
| 1083 | sliceType := reflect.SliceOf(valElemType) |
| 1084 | |
| 1085 | // If we have a non array/slice type then we first attempt to convert. |
| 1086 | if dataValKind != reflect.Array && dataValKind != reflect.Slice { |
| 1087 | if d.config.WeaklyTypedInput { |
| 1088 | switch { |
| 1089 | // Slice and array we use the normal logic |
| 1090 | case dataValKind == reflect.Slice, dataValKind == reflect.Array: |
| 1091 | break |
| 1092 | |
| 1093 | // Empty maps turn into empty slices |
| 1094 | case dataValKind == reflect.Map: |
| 1095 | if dataVal.Len() == 0 { |
| 1096 | val.Set(reflect.MakeSlice(sliceType, 0, 0)) |
| 1097 | return nil |
| 1098 | } |
| 1099 | // Create slice of maps of other sizes |
| 1100 | return d.decodeSlice(name, []interface{}{data}, val) |
| 1101 | |
| 1102 | case dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8: |
| 1103 | return d.decodeSlice(name, []byte(dataVal.String()), val) |
| 1104 | |
| 1105 | // All other types we try to convert to the slice type |
| 1106 | // and "lift" it into it. i.e. a string becomes a string slice. |
| 1107 | default: |
| 1108 | // Just re-try this function with data as a slice. |
| 1109 | return d.decodeSlice(name, []interface{}{data}, val) |
| 1110 | } |
| 1111 | } |
| 1112 | |
| 1113 | return fmt.Errorf( |
| 1114 | "'%s': source data must be an array or slice, got %s", name, dataValKind) |
| 1115 | } |
| 1116 | |
| 1117 | // If the input value is nil, then don't allocate since empty != nil |
| 1118 | if dataValKind != reflect.Array && dataVal.IsNil() { |
| 1119 | return nil |
| 1120 | } |
| 1121 | |
| 1122 | valSlice := val |
| 1123 | if valSlice.IsNil() || d.config.ZeroFields { |
| 1124 | // Make a new slice to hold our result, same size as the original data. |
| 1125 | valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len()) |
| 1126 | } |
| 1127 | |
| 1128 | // Accumulate any errors |
| 1129 | errors := make([]string, 0) |
| 1130 | |
| 1131 | for i := 0; i < dataVal.Len(); i++ { |
| 1132 | currentData := dataVal.Index(i).Interface() |
| 1133 | for valSlice.Len() <= i { |
| 1134 | valSlice = reflect.Append(valSlice, reflect.Zero(valElemType)) |
| 1135 | } |
no test coverage detected