package pgtype
import (
)
type BoolScanner interface {
ScanBool(v Bool) error
}
type BoolValuer interface {
BoolValue() (Bool, error)
}
type Bool struct {
Bool bool
Valid bool
}
func ( *Bool) ( Bool) error {
* =
return nil
}
func ( Bool) () (Bool, error) {
return , nil
}
func ( *Bool) ( any) error {
if == nil {
* = Bool{}
return nil
}
switch src := .(type) {
case bool:
* = Bool{Bool: , Valid: true}
return nil
case string:
, := strconv.ParseBool()
if != nil {
return
}
* = Bool{Bool: , Valid: true}
return nil
case []byte:
, := strconv.ParseBool(string())
if != nil {
return
}
* = Bool{Bool: , Valid: true}
return nil
}
return fmt.Errorf("cannot scan %T", )
}
func ( Bool) () (driver.Value, error) {
if !.Valid {
return nil, nil
}
return .Bool, nil
}
func ( Bool) () ([]byte, error) {
if !.Valid {
return []byte("null"), nil
}
if .Bool {
return []byte("true"), nil
} else {
return []byte("false"), nil
}
}
func ( *Bool) ( []byte) error {
var *bool
:= json.Unmarshal(, &)
if != nil {
return
}
if == nil {
* = Bool{}
} else {
* = Bool{Bool: *, Valid: true}
}
return nil
}
type BoolCodec struct{}
func (BoolCodec) ( int16) bool {
return == TextFormatCode || == BinaryFormatCode
}
func (BoolCodec) () int16 {
return BinaryFormatCode
}
func (BoolCodec) ( *Map, uint32, int16, any) EncodePlan {
switch {
case BinaryFormatCode:
switch .(type) {
case bool:
return encodePlanBoolCodecBinaryBool{}
case BoolValuer:
return encodePlanBoolCodecBinaryBoolValuer{}
}
case TextFormatCode:
switch .(type) {
case bool:
return encodePlanBoolCodecTextBool{}
case BoolValuer:
return encodePlanBoolCodecTextBoolValuer{}
}
}
return nil
}
type encodePlanBoolCodecBinaryBool struct{}
func (encodePlanBoolCodecBinaryBool) ( any, []byte) ( []byte, error) {
:= .(bool)
if {
= append(, 1)
} else {
= append(, 0)
}
return , nil
}
type encodePlanBoolCodecTextBoolValuer struct{}
func (encodePlanBoolCodecTextBoolValuer) ( any, []byte) ( []byte, error) {
, := .(BoolValuer).BoolValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
if .Bool {
= append(, 't')
} else {
= append(, 'f')
}
return , nil
}
type encodePlanBoolCodecBinaryBoolValuer struct{}
func (encodePlanBoolCodecBinaryBoolValuer) ( any, []byte) ( []byte, error) {
, := .(BoolValuer).BoolValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
if .Bool {
= append(, 1)
} else {
= append(, 0)
}
return , nil
}
type encodePlanBoolCodecTextBool struct{}
func (encodePlanBoolCodecTextBool) ( any, []byte) ( []byte, error) {
:= .(bool)
if {
= append(, 't')
} else {
= append(, 'f')
}
return , nil
}
func (BoolCodec) ( *Map, uint32, int16, any) ScanPlan {
switch {
case BinaryFormatCode:
switch .(type) {
case *bool:
return scanPlanBinaryBoolToBool{}
case BoolScanner:
return scanPlanBinaryBoolToBoolScanner{}
}
case TextFormatCode:
switch .(type) {
case *bool:
return scanPlanTextAnyToBool{}
case BoolScanner:
return scanPlanTextAnyToBoolScanner{}
}
}
return nil
}
func ( BoolCodec) ( *Map, uint32, int16, []byte) (driver.Value, error) {
return .DecodeValue(, , , )
}
func ( BoolCodec) ( *Map, uint32, int16, []byte) (any, error) {
if == nil {
return nil, nil
}
var bool
:= codecScan(, , , , , &)
if != nil {
return nil,
}
return , nil
}
type scanPlanBinaryBoolToBool struct{}
func (scanPlanBinaryBoolToBool) ( []byte, any) error {
if == nil {
return fmt.Errorf("cannot scan NULL into %T", )
}
if len() != 1 {
return fmt.Errorf("invalid length for bool: %v", len())
}
, := ().(*bool)
if ! {
return ErrScanTargetTypeChanged
}
* = [0] == 1
return nil
}
type scanPlanTextAnyToBool struct{}
func (scanPlanTextAnyToBool) ( []byte, any) error {
if == nil {
return fmt.Errorf("cannot scan NULL into %T", )
}
if len() == 0 {
return fmt.Errorf("cannot scan empty string into %T", )
}
, := ().(*bool)
if ! {
return ErrScanTargetTypeChanged
}
, := planTextToBool()
if != nil {
return
}
* =
return nil
}
type scanPlanBinaryBoolToBoolScanner struct{}
func (scanPlanBinaryBoolToBoolScanner) ( []byte, any) error {
, := ().(BoolScanner)
if ! {
return ErrScanTargetTypeChanged
}
if == nil {
return .ScanBool(Bool{})
}
if len() != 1 {
return fmt.Errorf("invalid length for bool: %v", len())
}
return .ScanBool(Bool{Bool: [0] == 1, Valid: true})
}
type scanPlanTextAnyToBoolScanner struct{}
func (scanPlanTextAnyToBoolScanner) ( []byte, any) error {
, := ().(BoolScanner)
if ! {
return ErrScanTargetTypeChanged
}
if == nil {
return .ScanBool(Bool{})
}
if len() == 0 {
return fmt.Errorf("cannot scan empty string into %T", )
}
, := planTextToBool()
if != nil {
return
}
return .ScanBool(Bool{Bool: , Valid: true})
}
func ( []byte) (bool, error) {
:= string(bytes.ToLower(bytes.TrimSpace()))
switch {
case strings.HasPrefix("true", ), strings.HasPrefix("yes", ), == "on", == "1":
return true, nil
case strings.HasPrefix("false", ), strings.HasPrefix("no", ), strings.HasPrefix("off", ), == "0":
return false, nil
default:
return false, fmt.Errorf("unknown boolean string representation %q", )
}
}