Files
chaisql/internal/types/boolean.go
2025-09-21 11:28:55 +05:30

203 lines
3.9 KiB
Go

package types
import (
"strconv"
"github.com/chaisql/chai/internal/encoding"
"github.com/cockroachdb/errors"
)
var _ TypeDefinition = BooleanTypeDef{}
type BooleanTypeDef struct{}
func (t BooleanTypeDef) Decode(src []byte) (Value, int) {
b := encoding.DecodeBoolean(src)
return NewBooleanValue(b), 1
}
func (BooleanTypeDef) IsComparableWith(other Type) bool {
return other == TypeBoolean
}
func (BooleanTypeDef) IsIndexComparableWith(other Type) bool {
return other == TypeBoolean
}
var _ Value = NewBooleanValue(false)
type BooleanValue bool
// NewBooleanValue returns a SQL BOOLEAN value.
func NewBooleanValue(x bool) BooleanValue {
return BooleanValue(x)
}
func (v BooleanValue) V() any {
return bool(v)
}
func (v BooleanValue) Type() Type {
return TypeBoolean
}
func (v BooleanValue) TypeDef() TypeDefinition {
return BooleanTypeDef{}
}
func (v BooleanValue) IsZero() (bool, error) {
return !bool(v), nil
}
func (v BooleanValue) String() string {
return strconv.FormatBool(bool(v))
}
func (v BooleanValue) MarshalText() ([]byte, error) {
return []byte(strconv.FormatBool(bool(v))), nil
}
func (v BooleanValue) MarshalJSON() ([]byte, error) {
return v.MarshalText()
}
func (v BooleanValue) Encode(dst []byte) ([]byte, error) {
return encoding.EncodeBoolean(dst, bool(v)), nil
}
func (v BooleanValue) EncodeAsKey(dst []byte) ([]byte, error) {
return v.Encode(dst)
}
func (v BooleanValue) CastAs(target Type) (Value, error) {
switch target {
case TypeBoolean:
return v, nil
case TypeInteger:
if bool(v) {
return NewIntegerValue(1), nil
}
return NewIntegerValue(0), nil
case TypeText:
return NewTextValue(v.String()), nil
}
return nil, errors.Errorf("cannot cast %q as %q", v.Type(), target)
}
func (v BooleanValue) ConvertToIndexedType(t Type) (Value, error) {
return v, nil
}
func (v BooleanValue) EQ(other Value) (bool, error) {
if other.Type() == TypeNull {
return false, nil
}
if other.Type() == TypeText {
tv, err := other.CastAs(TypeBoolean)
if err != nil {
return false, err
}
other = tv
}
if other.Type() != TypeBoolean {
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
}
return bool(v) == AsBool(other), nil
}
func (v BooleanValue) GT(other Value) (bool, error) {
if other.Type() == TypeNull {
return false, nil
}
if other.Type() == TypeText {
tv, err := other.CastAs(TypeBoolean)
if err != nil {
return false, err
}
other = tv
}
if other.Type() != TypeBoolean {
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
}
return bool(v) && !AsBool(other), nil
}
func (v BooleanValue) GTE(other Value) (bool, error) {
if other.Type() == TypeNull {
return false, nil
}
if other.Type() == TypeText {
tv, err := other.CastAs(TypeBoolean)
if err != nil {
return false, err
}
other = tv
}
if other.Type() != TypeBoolean {
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
}
bv := bool(v)
return bv == AsBool(other) || bv, nil
}
func (v BooleanValue) LT(other Value) (bool, error) {
if other.Type() == TypeNull {
return false, nil
}
if other.Type() == TypeText {
tv, err := other.CastAs(TypeBoolean)
if err != nil {
return false, err
}
other = tv
}
if other.Type() != TypeBoolean {
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
}
return !bool(v) && AsBool(other), nil
}
func (v BooleanValue) LTE(other Value) (bool, error) {
if other.Type() == TypeNull {
return false, nil
}
if other.Type() == TypeText {
tv, err := other.CastAs(TypeBoolean)
if err != nil {
return false, err
}
other = tv
}
if other.Type() != TypeBoolean {
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
}
bv := bool(v)
return bv == AsBool(other) || !bv, nil
}
func (v BooleanValue) Between(a, b Value) (bool, error) {
ok, err := v.GTE(a)
if err != nil || !ok {
return false, err
}
return v.LTE(b)
}