refQualify attempts to convert the value to a CEL value and then uses reflection methods to try and apply the qualifier with the option to presence test field accesses before retrieving field values.
(adapter types.Adapter, obj any, idx ref.Val, presenceTest, presenceOnly, errorOnBadPresenceTest bool)
| 1366 | // refQualify attempts to convert the value to a CEL value and then uses reflection methods to try and |
| 1367 | // apply the qualifier with the option to presence test field accesses before retrieving field values. |
| 1368 | func refQualify(adapter types.Adapter, obj any, idx ref.Val, presenceTest, presenceOnly, errorOnBadPresenceTest bool) (ref.Val, bool, error) { |
| 1369 | celVal := adapter.NativeToValue(obj) |
| 1370 | switch v := celVal.(type) { |
| 1371 | case *types.Unknown: |
| 1372 | return v, true, nil |
| 1373 | case *types.Err: |
| 1374 | return nil, false, v |
| 1375 | case traits.Mapper: |
| 1376 | val, found := v.Find(idx) |
| 1377 | // If the index is of the wrong type for the map, then it is possible |
| 1378 | // for the Find call to produce an error. |
| 1379 | if types.IsError(val) { |
| 1380 | return nil, false, val.(*types.Err) |
| 1381 | } |
| 1382 | if found { |
| 1383 | return val, true, nil |
| 1384 | } |
| 1385 | if presenceTest { |
| 1386 | return nil, false, nil |
| 1387 | } |
| 1388 | return nil, false, missingKey(idx) |
| 1389 | case traits.Lister: |
| 1390 | // If the index argument is not a valid numeric type, then it is possible |
| 1391 | // for the index operation to produce an error. |
| 1392 | i, err := types.IndexOrError(idx) |
| 1393 | if err != nil { |
| 1394 | return nil, false, err |
| 1395 | } |
| 1396 | celIndex := types.Int(i) |
| 1397 | if i >= 0 && celIndex < v.Size().(types.Int) { |
| 1398 | return v.Get(idx), true, nil |
| 1399 | } |
| 1400 | if presenceTest { |
| 1401 | return nil, false, nil |
| 1402 | } |
| 1403 | return nil, false, missingIndex(idx) |
| 1404 | case traits.Indexer: |
| 1405 | if presenceTest { |
| 1406 | ft, ok := v.(traits.FieldTester) |
| 1407 | if ok { |
| 1408 | presence := ft.IsSet(idx) |
| 1409 | if types.IsError(presence) { |
| 1410 | return nil, false, presence.(*types.Err) |
| 1411 | } |
| 1412 | // If not found or presence only test, then return. |
| 1413 | // Otherwise, if found, obtain the value later on. |
| 1414 | if presenceOnly || presence == types.False { |
| 1415 | return nil, presence == types.True, nil |
| 1416 | } |
| 1417 | } |
| 1418 | } |
| 1419 | val := v.Get(idx) |
| 1420 | if types.IsError(val) { |
| 1421 | return nil, false, val.(*types.Err) |
| 1422 | } |
| 1423 | return val, true, nil |
| 1424 | default: |
| 1425 | if presenceTest && !errorOnBadPresenceTest { |
no test coverage detected