package pgtype

import (
	
	
	
	
	
	

	
)

type Float64Scanner interface {
	ScanFloat64(Float8) error
}

type Float64Valuer interface {
	Float64Value() (Float8, error)
}

type Float8 struct {
	Float64 float64
	Valid   bool
}

// ScanFloat64 implements the Float64Scanner interface.
func ( *Float8) ( Float8) error {
	* = 
	return nil
}

func ( Float8) () (Float8, error) {
	return , nil
}

func ( *Float8) ( Int8) error {
	* = Float8{Float64: float64(.Int64), Valid: .Valid}
	return nil
}

func ( Float8) () (Int8, error) {
	return Int8{Int64: int64(.Float64), Valid: .Valid}, nil
}

// Scan implements the database/sql Scanner interface.
func ( *Float8) ( any) error {
	if  == nil {
		* = Float8{}
		return nil
	}

	switch src := .(type) {
	case float64:
		* = Float8{Float64: , Valid: true}
		return nil
	case string:
		,  := strconv.ParseFloat(string(), 64)
		if  != nil {
			return 
		}
		* = Float8{Float64: , Valid: true}
		return nil
	}

	return fmt.Errorf("cannot scan %T", )
}

// Value implements the database/sql/driver Valuer interface.
func ( Float8) () (driver.Value, error) {
	if !.Valid {
		return nil, nil
	}
	return .Float64, nil
}

type Float8Codec struct{}

func (Float8Codec) ( int16) bool {
	return  == TextFormatCode ||  == BinaryFormatCode
}

func (Float8Codec) () int16 {
	return BinaryFormatCode
}

func (Float8Codec) ( *Map,  uint32,  int16,  any) EncodePlan {
	switch  {
	case BinaryFormatCode:
		switch .(type) {
		case float64:
			return encodePlanFloat8CodecBinaryFloat64{}
		case Float64Valuer:
			return encodePlanFloat8CodecBinaryFloat64Valuer{}
		case Int64Valuer:
			return encodePlanFloat8CodecBinaryInt64Valuer{}
		}
	case TextFormatCode:
		switch .(type) {
		case float64:
			return encodePlanTextFloat64{}
		case Float64Valuer:
			return encodePlanTextFloat64Valuer{}
		case Int64Valuer:
			return encodePlanTextInt64Valuer{}
		}
	}

	return nil
}

func ( *Float8) () ([]byte, error) {
	if !.Valid {
		return []byte("null"), nil
	}
	return json.Marshal(.Float64)
}

type encodePlanFloat8CodecBinaryFloat64 struct{}

func (encodePlanFloat8CodecBinaryFloat64) ( any,  []byte) ( []byte,  error) {
	 := .(float64)
	return pgio.AppendUint64(, math.Float64bits()), nil
}

type encodePlanTextFloat64 struct{}

func (encodePlanTextFloat64) ( any,  []byte) ( []byte,  error) {
	 := .(float64)
	return append(, strconv.FormatFloat(, 'f', -1, 64)...), nil
}

type encodePlanFloat8CodecBinaryFloat64Valuer struct{}

func (encodePlanFloat8CodecBinaryFloat64Valuer) ( any,  []byte) ( []byte,  error) {
	,  := .(Float64Valuer).Float64Value()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	return pgio.AppendUint64(, math.Float64bits(.Float64)), nil
}

type encodePlanTextFloat64Valuer struct{}

func (encodePlanTextFloat64Valuer) ( any,  []byte) ( []byte,  error) {
	,  := .(Float64Valuer).Float64Value()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	return append(, strconv.FormatFloat(.Float64, 'f', -1, 64)...), nil
}

type encodePlanFloat8CodecBinaryInt64Valuer struct{}

func (encodePlanFloat8CodecBinaryInt64Valuer) ( any,  []byte) ( []byte,  error) {
	,  := .(Int64Valuer).Int64Value()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	 := float64(.Int64)
	return pgio.AppendUint64(, math.Float64bits()), nil
}

type encodePlanTextInt64Valuer struct{}

func (encodePlanTextInt64Valuer) ( any,  []byte) ( []byte,  error) {
	,  := .(Int64Valuer).Int64Value()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	return append(, strconv.FormatInt(.Int64, 10)...), nil
}

func (Float8Codec) ( *Map,  uint32,  int16,  any) ScanPlan {

	switch  {
	case BinaryFormatCode:
		switch .(type) {
		case *float64:
			return scanPlanBinaryFloat8ToFloat64{}
		case Float64Scanner:
			return scanPlanBinaryFloat8ToFloat64Scanner{}
		case Int64Scanner:
			return scanPlanBinaryFloat8ToInt64Scanner{}
		case TextScanner:
			return scanPlanBinaryFloat8ToTextScanner{}
		}
	case TextFormatCode:
		switch .(type) {
		case *float64:
			return scanPlanTextAnyToFloat64{}
		case Float64Scanner:
			return scanPlanTextAnyToFloat64Scanner{}
		case Int64Scanner:
			return scanPlanTextAnyToInt64Scanner{}
		}
	}

	return nil
}

type scanPlanBinaryFloat8ToFloat64 struct{}

func (scanPlanBinaryFloat8ToFloat64) ( []byte,  any) error {
	if  == nil {
		return fmt.Errorf("cannot scan NULL into %T", )
	}

	if len() != 8 {
		return fmt.Errorf("invalid length for float8: %v", len())
	}

	 := int64(binary.BigEndian.Uint64())
	 := ().(*float64)
	* = math.Float64frombits(uint64())

	return nil
}

type scanPlanBinaryFloat8ToFloat64Scanner struct{}

func (scanPlanBinaryFloat8ToFloat64Scanner) ( []byte,  any) error {
	 := ().(Float64Scanner)

	if  == nil {
		return .ScanFloat64(Float8{})
	}

	if len() != 8 {
		return fmt.Errorf("invalid length for float8: %v", len())
	}

	 := int64(binary.BigEndian.Uint64())
	return .ScanFloat64(Float8{Float64: math.Float64frombits(uint64()), Valid: true})
}

type scanPlanBinaryFloat8ToInt64Scanner struct{}

func (scanPlanBinaryFloat8ToInt64Scanner) ( []byte,  any) error {
	 := ().(Int64Scanner)

	if  == nil {
		return .ScanInt64(Int8{})
	}

	if len() != 8 {
		return fmt.Errorf("invalid length for float8: %v", len())
	}

	 := int64(binary.BigEndian.Uint64())
	 := math.Float64frombits(uint64())
	 := int64()
	if  != float64() {
		return fmt.Errorf("cannot losslessly convert %v to int64", )
	}

	return .ScanInt64(Int8{Int64: , Valid: true})
}

type scanPlanBinaryFloat8ToTextScanner struct{}

func (scanPlanBinaryFloat8ToTextScanner) ( []byte,  any) error {
	 := ().(TextScanner)

	if  == nil {
		return .ScanText(Text{})
	}

	if len() != 8 {
		return fmt.Errorf("invalid length for float8: %v", len())
	}

	 := int64(binary.BigEndian.Uint64())
	 := math.Float64frombits(uint64())

	return .ScanText(Text{String: strconv.FormatFloat(, 'f', -1, 64), Valid: true})
}

type scanPlanTextAnyToFloat64 struct{}

func (scanPlanTextAnyToFloat64) ( []byte,  any) error {
	if  == nil {
		return fmt.Errorf("cannot scan NULL into %T", )
	}

	,  := strconv.ParseFloat(string(), 64)
	if  != nil {
		return 
	}

	 := ().(*float64)
	* = 

	return nil
}

type scanPlanTextAnyToFloat64Scanner struct{}

func (scanPlanTextAnyToFloat64Scanner) ( []byte,  any) error {
	 := ().(Float64Scanner)

	if  == nil {
		return .ScanFloat64(Float8{})
	}

	,  := strconv.ParseFloat(string(), 64)
	if  != nil {
		return 
	}

	return .ScanFloat64(Float8{Float64: , Valid: true})
}

func ( Float8Codec) ( *Map,  uint32,  int16,  []byte) (driver.Value, error) {
	return .DecodeValue(, , , )
}

func ( Float8Codec) ( *Map,  uint32,  int16,  []byte) (any, error) {
	if  == nil {
		return nil, nil
	}

	var  float64
	 := codecScan(, , , , , &)
	if  != nil {
		return nil, 
	}
	return , nil
}