url_values.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package expressions
  2. import (
  3. "errors"
  4. "net/url"
  5. "reflect"
  6. "strings"
  7. "github.com/google/cel-go/common/types"
  8. "github.com/google/cel-go/common/types/ref"
  9. "github.com/google/cel-go/common/types/traits"
  10. )
  11. var ErrNotImplemented = errors.New("expressions: not implemented")
  12. // URLValues is a type wrapper to expose url.Values into CEL programs.
  13. type URLValues struct {
  14. url.Values
  15. }
  16. func (u URLValues) ConvertToNative(typeDesc reflect.Type) (any, error) {
  17. return nil, ErrNotImplemented
  18. }
  19. func (u URLValues) ConvertToType(typeVal ref.Type) ref.Val {
  20. switch typeVal {
  21. case types.MapType:
  22. return u
  23. case types.TypeType:
  24. return types.MapType
  25. }
  26. return types.NewErr("can't convert from %q to %q", types.MapType, typeVal)
  27. }
  28. func (u URLValues) Equal(other ref.Val) ref.Val {
  29. return types.Bool(false) // We don't want to compare header maps
  30. }
  31. func (u URLValues) Type() ref.Type {
  32. return types.MapType
  33. }
  34. func (u URLValues) Value() any { return u }
  35. func (u URLValues) Find(key ref.Val) (ref.Val, bool) {
  36. k, ok := key.(types.String)
  37. if !ok {
  38. return nil, false
  39. }
  40. if _, ok := u.Values[string(k)]; !ok {
  41. return nil, false
  42. }
  43. return types.String(strings.Join(u.Values[string(k)], ",")), true
  44. }
  45. func (u URLValues) Contains(key ref.Val) ref.Val {
  46. _, ok := u.Find(key)
  47. return types.Bool(ok)
  48. }
  49. func (u URLValues) Get(key ref.Val) ref.Val {
  50. result, ok := u.Find(key)
  51. if !ok {
  52. return types.ValOrErr(result, "no such key: %v", key)
  53. }
  54. return result
  55. }
  56. func (u URLValues) Iterator() traits.Iterator { panic("TODO(Xe): implement me") }
  57. func (u URLValues) IsZeroValue() bool {
  58. return len(u.Values) == 0
  59. }
  60. func (u URLValues) Size() ref.Val { return types.Int(len(u.Values)) }