159 lines
3.1 KiB
Go
159 lines
3.1 KiB
Go
package condition
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/google/cel-go/common/types"
|
|
"github.com/google/cel-go/common/types/ref"
|
|
"github.com/google/cel-go/common/types/traits"
|
|
"net/textproto"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
type mimeLike struct {
|
|
m textproto.MIMEHeader
|
|
}
|
|
|
|
func (a mimeLike) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
|
return nil, fmt.Errorf("type conversion error from map to '%v'", typeDesc)
|
|
}
|
|
|
|
func (a mimeLike) ConvertToType(typeVal ref.Type) ref.Val {
|
|
switch typeVal {
|
|
case types.MapType:
|
|
return a
|
|
case types.TypeType:
|
|
return types.MapType
|
|
}
|
|
return types.NewErr("type conversion error from '%s' to '%s'", types.MapType, typeVal)
|
|
}
|
|
|
|
func (a mimeLike) Equal(other ref.Val) ref.Val {
|
|
return types.Bool(false)
|
|
}
|
|
|
|
func (a mimeLike) Type() ref.Type {
|
|
return types.MapType
|
|
}
|
|
|
|
func (a mimeLike) Value() any {
|
|
return a.m
|
|
}
|
|
|
|
func (a mimeLike) Contains(key ref.Val) ref.Val {
|
|
_, found := a.Find(key)
|
|
return types.Bool(found)
|
|
}
|
|
|
|
func (a mimeLike) Get(key ref.Val) ref.Val {
|
|
v, found := a.Find(key)
|
|
if !found {
|
|
return types.ValOrErr(v, "no such key: %v", key)
|
|
}
|
|
return v
|
|
}
|
|
|
|
func (a mimeLike) Iterator() traits.Iterator {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (a mimeLike) IsZeroValue() bool {
|
|
return len(a.m) == 0
|
|
}
|
|
|
|
func (a mimeLike) Size() ref.Val {
|
|
return types.Int(len(a.m))
|
|
}
|
|
|
|
func (a mimeLike) Find(key ref.Val) (ref.Val, bool) {
|
|
k, ok := key.(types.String)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return singleVal(a.m.Values(string(k)), true)
|
|
}
|
|
|
|
type valuesLike struct {
|
|
m map[string][]string
|
|
}
|
|
|
|
func (a valuesLike) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
|
return nil, fmt.Errorf("type conversion error from map to '%v'", typeDesc)
|
|
}
|
|
|
|
func (a valuesLike) ConvertToType(typeVal ref.Type) ref.Val {
|
|
switch typeVal {
|
|
case types.MapType:
|
|
return a
|
|
case types.TypeType:
|
|
return types.MapType
|
|
}
|
|
return types.NewErr("type conversion error from '%s' to '%s'", types.MapType, typeVal)
|
|
}
|
|
|
|
func (a valuesLike) Equal(other ref.Val) ref.Val {
|
|
return types.Bool(false)
|
|
}
|
|
|
|
func (a valuesLike) Type() ref.Type {
|
|
return types.MapType
|
|
}
|
|
|
|
func (a valuesLike) Value() any {
|
|
return a.m
|
|
}
|
|
|
|
func (a valuesLike) Contains(key ref.Val) ref.Val {
|
|
_, found := a.Find(key)
|
|
return types.Bool(found)
|
|
}
|
|
|
|
func (a valuesLike) Get(key ref.Val) ref.Val {
|
|
v, found := a.Find(key)
|
|
if !found {
|
|
return types.ValOrErr(v, "no such key: %v", key)
|
|
}
|
|
return v
|
|
}
|
|
|
|
func (a valuesLike) Iterator() traits.Iterator {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (a valuesLike) IsZeroValue() bool {
|
|
return len(a.m) == 0
|
|
}
|
|
|
|
func (a valuesLike) Size() ref.Val {
|
|
return types.Int(len(a.m))
|
|
}
|
|
|
|
func (a valuesLike) Find(key ref.Val) (ref.Val, bool) {
|
|
k, ok := key.(types.String)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
val, ok := a.m[string(k)]
|
|
return singleVal(val, ok)
|
|
}
|
|
|
|
func singleVal(values []string, ok bool) (ref.Val, bool) {
|
|
if len(values) == 0 || !ok {
|
|
return nil, false
|
|
}
|
|
if len(values) > 1 {
|
|
return types.String(strings.Join(values, ",")), true
|
|
}
|
|
return types.String(values[0]), true
|
|
}
|
|
|
|
func NewMIMEMap(m textproto.MIMEHeader) traits.Mapper {
|
|
return mimeLike{m: m}
|
|
}
|
|
|
|
func NewValuesMap(m map[string][]string) traits.Mapper {
|
|
return valuesLike{m: m}
|
|
}
|