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

Method decodeStructFromMap

mapstructure.go:1265–1482  ·  view source on GitHub ↗
(name string, dataVal, val reflect.Value)

Source from the content-addressed store, hash-verified

1263}
1264
1265func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {
1266 dataValType := dataVal.Type()
1267 if kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {
1268 return fmt.Errorf(
1269 "'%s' needs a map with string keys, has '%s' keys",
1270 name, dataValType.Key().Kind())
1271 }
1272
1273 dataValKeys := make(map[reflect.Value]struct{})
1274 dataValKeysUnused := make(map[interface{}]struct{})
1275 for _, dataValKey := range dataVal.MapKeys() {
1276 dataValKeys[dataValKey] = struct{}{}
1277 dataValKeysUnused[dataValKey.Interface()] = struct{}{}
1278 }
1279
1280 targetValKeysUnused := make(map[interface{}]struct{})
1281 errors := make([]string, 0)
1282
1283 // This slice will keep track of all the structs we'll be decoding.
1284 // There can be more than one struct if there are embedded structs
1285 // that are squashed.
1286 structs := make([]reflect.Value, 1, 5)
1287 structs[0] = val
1288
1289 // Compile the list of all the fields that we're going to be decoding
1290 // from all the structs.
1291 type field struct {
1292 field reflect.StructField
1293 val reflect.Value
1294 }
1295
1296 // remainField is set to a valid field set with the "remain" tag if
1297 // we are keeping track of remaining values.
1298 var remainField *field
1299
1300 fields := []field{}
1301 for len(structs) > 0 {
1302 structVal := structs[0]
1303 structs = structs[1:]
1304
1305 structType := structVal.Type()
1306
1307 for i := 0; i < structType.NumField(); i++ {
1308 fieldType := structType.Field(i)
1309 fieldVal := structVal.Field(i)
1310 if fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {
1311 // Handle embedded struct pointers as embedded structs.
1312 fieldVal = fieldVal.Elem()
1313 }
1314
1315 // If "squash" is specified in the tag, we squash the field down.
1316 squash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous
1317 remain := false
1318
1319 // We always parse the tags cause we're looking for other tags too
1320 tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
1321 for _, tag := range tagParts[1:] {
1322 if tag == "squash" {

Callers 1

decodeStructMethod · 0.95

Calls 3

decodeMethod · 0.95
decodeMapMethod · 0.95
appendErrorsFunction · 0.85

Tested by

no test coverage detected