MCPcopy
hub / github.com/mitchellh/mapstructure / decodeSlice

Method decodeSlice

mapstructure.go:1078–1153  ·  view source on GitHub ↗
(name string, data interface{}, val reflect.Value)

Source from the content-addressed store, hash-verified

1076}
1077
1078func (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 }

Callers 1

decodeMethod · 0.95

Calls 2

decodeMethod · 0.95
appendErrorsFunction · 0.85

Tested by

no test coverage detected