ConvertToNative implements the ref.Val interface method. CEL does not have a notion of pointers, so whether a field is a pointer or value is handled as part of this conversion step.
(typeDesc reflect.Type)
| 480 | // CEL does not have a notion of pointers, so whether a field is a pointer or value |
| 481 | // is handled as part of this conversion step. |
| 482 | func (o *nativeObj) ConvertToNative(typeDesc reflect.Type) (any, error) { |
| 483 | if o.refValue.Type() == typeDesc { |
| 484 | return o.val, nil |
| 485 | } |
| 486 | if o.refValue.Kind() == reflect.Pointer && o.refValue.Type().Elem() == typeDesc { |
| 487 | return o.refValue.Elem().Interface(), nil |
| 488 | } |
| 489 | if typeDesc.Kind() == reflect.Pointer && o.refValue.Type() == typeDesc.Elem() { |
| 490 | ptr := reflect.New(typeDesc.Elem()) |
| 491 | ptr.Elem().Set(o.refValue) |
| 492 | return ptr.Interface(), nil |
| 493 | } |
| 494 | switch typeDesc { |
| 495 | case jsonValueType: |
| 496 | jsonStruct, err := o.ConvertToNative(jsonStructType) |
| 497 | if err != nil { |
| 498 | return nil, err |
| 499 | } |
| 500 | return structpb.NewStructValue(jsonStruct.(*structpb.Struct)), nil |
| 501 | case jsonStructType: |
| 502 | refVal := reflect.Indirect(o.refValue) |
| 503 | refType := refVal.Type() |
| 504 | fields := make(map[string]*structpb.Value, refVal.NumField()) |
| 505 | for i := 0; i < refVal.NumField(); i++ { |
| 506 | fieldType := refType.Field(i) |
| 507 | fieldValue := refVal.Field(i) |
| 508 | if !fieldValue.IsValid() || fieldValue.IsZero() { |
| 509 | continue |
| 510 | } |
| 511 | fieldName := toFieldName(o.valType.fieldNameHandler, fieldType) |
| 512 | fieldCELVal := o.NativeToValue(fieldValue.Interface()) |
| 513 | fieldJSONVal, err := fieldCELVal.ConvertToNative(jsonValueType) |
| 514 | if err != nil { |
| 515 | return nil, err |
| 516 | } |
| 517 | fields[fieldName] = fieldJSONVal.(*structpb.Value) |
| 518 | } |
| 519 | return &structpb.Struct{Fields: fields}, nil |
| 520 | } |
| 521 | return nil, fmt.Errorf("type conversion error from '%v' to '%v'", o.Type(), typeDesc) |
| 522 | } |
| 523 | |
| 524 | // ConvertToType implements the ref.Val interface method. |
| 525 | func (o *nativeObj) ConvertToType(typeVal ref.Type) ref.Val { |
nothing calls this directly
no test coverage detected