(name string, data interface{}, val reflect.Value)
| 1153 | } |
| 1154 | |
| 1155 | func (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error { |
| 1156 | dataVal := reflect.Indirect(reflect.ValueOf(data)) |
| 1157 | dataValKind := dataVal.Kind() |
| 1158 | valType := val.Type() |
| 1159 | valElemType := valType.Elem() |
| 1160 | arrayType := reflect.ArrayOf(valType.Len(), valElemType) |
| 1161 | |
| 1162 | valArray := val |
| 1163 | |
| 1164 | if valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields { |
| 1165 | // Check input type |
| 1166 | if dataValKind != reflect.Array && dataValKind != reflect.Slice { |
| 1167 | if d.config.WeaklyTypedInput { |
| 1168 | switch { |
| 1169 | // Empty maps turn into empty arrays |
| 1170 | case dataValKind == reflect.Map: |
| 1171 | if dataVal.Len() == 0 { |
| 1172 | val.Set(reflect.Zero(arrayType)) |
| 1173 | return nil |
| 1174 | } |
| 1175 | |
| 1176 | // All other types we try to convert to the array type |
| 1177 | // and "lift" it into it. i.e. a string becomes a string array. |
| 1178 | default: |
| 1179 | // Just re-try this function with data as a slice. |
| 1180 | return d.decodeArray(name, []interface{}{data}, val) |
| 1181 | } |
| 1182 | } |
| 1183 | |
| 1184 | return fmt.Errorf( |
| 1185 | "'%s': source data must be an array or slice, got %s", name, dataValKind) |
| 1186 | |
| 1187 | } |
| 1188 | if dataVal.Len() > arrayType.Len() { |
| 1189 | return fmt.Errorf( |
| 1190 | "'%s': expected source data to have length less or equal to %d, got %d", name, arrayType.Len(), dataVal.Len()) |
| 1191 | |
| 1192 | } |
| 1193 | |
| 1194 | // Make a new array to hold our result, same size as the original data. |
| 1195 | valArray = reflect.New(arrayType).Elem() |
| 1196 | } |
| 1197 | |
| 1198 | // Accumulate any errors |
| 1199 | errors := make([]string, 0) |
| 1200 | |
| 1201 | for i := 0; i < dataVal.Len(); i++ { |
| 1202 | currentData := dataVal.Index(i).Interface() |
| 1203 | currentField := valArray.Index(i) |
| 1204 | |
| 1205 | fieldName := name + "[" + strconv.Itoa(i) + "]" |
| 1206 | if err := d.decode(fieldName, currentData, currentField); err != nil { |
| 1207 | errors = appendErrors(errors, err) |
| 1208 | } |
| 1209 | } |
| 1210 | |
| 1211 | // Finally, set the value to the array we built up |
| 1212 | val.Set(valArray) |
no test coverage detected