CELValueToMapStrList converts a CEL value to a map[string][]string Earlier validation stages should guarantee that the value has this type at compile time, and that the runtime value type is map[string]any. The reason for the slight difference in value type is that CEL allows for map literals conta
(data ref.Val)
| 667 | // map literals containing heterogeneous values, in this case string and list |
| 668 | // of string. |
| 669 | func CELValueToMapStrList(data ref.Val) (map[string][]string, error) { |
| 670 | // Prefer map[string]any, but newer cel-go versions may return map[any]any |
| 671 | mapStrType := reflect.TypeFor[map[string]any]() |
| 672 | mapStrRaw, err := data.ConvertToNative(mapStrType) |
| 673 | var mapStrIface map[string]any |
| 674 | if err != nil { |
| 675 | // Try map[any]any and convert keys to strings |
| 676 | mapAnyType := reflect.TypeFor[map[any]any]() |
| 677 | mapAnyRaw, err2 := data.ConvertToNative(mapAnyType) |
| 678 | if err2 != nil { |
| 679 | return nil, err |
| 680 | } |
| 681 | mapAnyIface := mapAnyRaw.(map[any]any) |
| 682 | mapStrIface = make(map[string]any, len(mapAnyIface)) |
| 683 | for k, v := range mapAnyIface { |
| 684 | ks, ok := k.(string) |
| 685 | if !ok { |
| 686 | return nil, fmt.Errorf("unsupported map key type in header match: %T", k) |
| 687 | } |
| 688 | mapStrIface[ks] = v |
| 689 | } |
| 690 | } else { |
| 691 | mapStrIface = mapStrRaw.(map[string]any) |
| 692 | } |
| 693 | mapStrListStr := make(map[string][]string, len(mapStrIface)) |
| 694 | for k, v := range mapStrIface { |
| 695 | switch val := v.(type) { |
| 696 | case string: |
| 697 | mapStrListStr[k] = []string{val} |
| 698 | case types.String: |
| 699 | mapStrListStr[k] = []string{string(val)} |
| 700 | case []string: |
| 701 | mapStrListStr[k] = val |
| 702 | case []ref.Val: |
| 703 | convVals := make([]string, len(val)) |
| 704 | for i, elem := range val { |
| 705 | strVal, ok := elem.(types.String) |
| 706 | if !ok { |
| 707 | return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) |
| 708 | } |
| 709 | convVals[i] = string(strVal) |
| 710 | } |
| 711 | mapStrListStr[k] = convVals |
| 712 | case []any: |
| 713 | convVals := make([]string, len(val)) |
| 714 | for i, elem := range val { |
| 715 | switch e := elem.(type) { |
| 716 | case string: |
| 717 | convVals[i] = e |
| 718 | case types.String: |
| 719 | convVals[i] = string(e) |
| 720 | default: |
| 721 | return nil, fmt.Errorf("unsupported element type in matcher input list: %T", elem) |
| 722 | } |
| 723 | } |
| 724 | mapStrListStr[k] = convVals |
| 725 | default: |
| 726 | return nil, fmt.Errorf("unsupported value type in matcher input: %T", val) |
no test coverage detected