MCPcopy
hub / github.com/pelletier/go-toml / descend

Method descend

unmarshaler.go:1384–1546  ·  view source on GitHub ↗

descend walks the given key path into v, and assigns the value at the end. It returns the value to store back at this level. An invalid value means nothing should be stored (e.g. unknown field).

(v reflect.Value, path []pathPart, idx int, expr *unstable.Node, value *unstable.Node)

Source from the content-addressed store, hash-verified

1382// end. It returns the value to store back at this level. An invalid value
1383// means nothing should be stored (e.g. unknown field).
1384func (d *decoder) descend(v reflect.Value, path []pathPart, idx int, expr *unstable.Node, value *unstable.Node) (reflect.Value, error) {
1385 if idx == len(path) {
1386 return d.assignValue(v, expr, value)
1387 }
1388
1389 if v.Kind() == reflect.Ptr {
1390 if v.IsNil() {
1391 v.Set(reflect.New(v.Type().Elem()))
1392 }
1393 nv, err := d.descend(v.Elem(), path, idx, expr, value)
1394 if err != nil || !nv.IsValid() {
1395 return reflect.Value{}, err
1396 }
1397 v.Elem().Set(nv)
1398 return v, nil
1399 }
1400
1401 // A target implementing the unmarshaler interface consumes the value,
1402 // whatever the remaining parts of the key are.
1403 if d.unmarshalerInterface {
1404 if u, ok := unmarshalerOf(v); ok {
1405 return v, u.UnmarshalTOML(d.rawValue(expr, value))
1406 }
1407 }
1408
1409 part := path[idx]
1410
1411 switch v.Kind() {
1412 case reflect.Map:
1413 // Native fast path for the most common generic target: walk the
1414 // remaining dotted-key path with plain Go map operations and decode
1415 // the value directly, skipping the reflect.Value round-trips
1416 // (stringMapKey, MapIndex, New, SetMapIndex) entirely.
1417 if !d.unmarshalerInterface && v.Type() == mapStringInterfaceType {
1418 return d.descendStrMap(v, path, idx, value)
1419 }
1420 var name string
1421 var key reflect.Value
1422 var err error
1423 fastKey := v.Type().Key() == stringType
1424 if fastKey {
1425 name = d.partString(&part)
1426 key = d.stringMapKey(name)
1427 } else {
1428 key, err = makeMapKey(v.Type().Key(), d.partString(&part))
1429 if err != nil {
1430 return reflect.Value{}, err
1431 }
1432 }
1433 if v.IsNil() {
1434 v = reflect.MakeMap(v.Type())
1435 }
1436 elemType := v.Type().Elem()
1437 existing := v.MapIndex(key)
1438 var elem reflect.Value
1439 switch {
1440 case existing.IsValid():
1441 elem = reflect.New(elemType).Elem()

Callers 2

assignInlineTableMethod · 0.95

Calls 15

assignValueMethod · 0.95
rawValueMethod · 0.95
descendStrMapMethod · 0.95
partStringMethod · 0.95
stringMapKeyMethod · 0.95
arrayCountMethod · 0.95
joinPathMethod · 0.95
typeMismatchErrorMethod · 0.95
NewParserErrorFunction · 0.92
unmarshalerOfFunction · 0.85
makeMapKeyFunction · 0.85
planForTypeFunction · 0.85

Tested by

no test coverage detected