package types
import (
"fmt"
"reflect"
"strconv"
"github.com/google/cel-go/common/types/ref"
anypb "google.golang.org/protobuf/types/known/anypb"
structpb "google.golang.org/protobuf/types/known/structpb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
)
type Bool bool
var (
boolWrapperType = reflect.TypeOf(&wrapperspb.BoolValue{})
)
const (
False = Bool(false)
True = Bool(true)
)
func (b Bool) Compare(other ref.Val) ref.Val {
otherBool, ok := other.(Bool)
if !ok {
return ValOrErr(other, "no such overload")
}
if b == otherBool {
return IntZero
}
if !b && otherBool {
return IntNegOne
}
return IntOne
}
func (b Bool) ConvertToNative(typeDesc reflect.Type) (any, error) {
switch typeDesc.Kind() {
case reflect.Bool:
return reflect.ValueOf(b).Convert(typeDesc).Interface(), nil
case reflect.Ptr:
switch typeDesc {
case anyValueType:
return anypb.New(wrapperspb.Bool(bool(b)))
case boolWrapperType:
return wrapperspb.Bool(bool(b)), nil
case jsonValueType:
return structpb.NewBoolValue(bool(b)), nil
default:
if typeDesc.Elem().Kind() == reflect.Bool {
p := bool(b)
return &p, nil
}
}
case reflect.Interface:
bv := b.Value()
if reflect.TypeOf(bv).Implements(typeDesc) {
return bv, nil
}
if reflect.TypeOf(b).Implements(typeDesc) {
return b, nil
}
}
return nil, fmt.Errorf("type conversion error from bool to '%v'", typeDesc)
}
func (b Bool) ConvertToType(typeVal ref.Type) ref.Val {
switch typeVal {
case StringType:
return String(strconv.FormatBool(bool(b)))
case BoolType:
return b
case TypeType:
return BoolType
}
return NewErr("type conversion error from '%v' to '%v'", BoolType, typeVal)
}
func (b Bool) Equal(other ref.Val) ref.Val {
otherBool, ok := other.(Bool)
return Bool(ok && b == otherBool)
}
func (b Bool) IsZeroValue() bool {
return b == False
}
func (b Bool) Negate() ref.Val {
return !b
}
func (b Bool) Type() ref.Type {
return BoolType
}
func (b Bool) Value() any {
return bool(b)
}
func IsBool(elem ref.Val) bool {
switch v := elem.(type) {
case Bool:
return true
case ref.Val:
return v.Type() == BoolType
default:
return false
}
}