package pgtype
import (
)
type LineScanner interface {
ScanLine(v Line) error
}
type LineValuer interface {
LineValue() (Line, error)
}
type Line struct {
A, B, C float64
Valid bool
}
func ( *Line) ( Line) error {
* =
return nil
}
func ( Line) () (Line, error) {
return , nil
}
func ( *Line) ( any) error {
return fmt.Errorf("cannot convert %v to Line", )
}
func ( *Line) ( any) error {
if == nil {
* = Line{}
return nil
}
switch src := .(type) {
case string:
return scanPlanTextAnyToLineScanner{}.Scan([]byte(), )
}
return fmt.Errorf("cannot scan %T", )
}
func ( Line) () (driver.Value, error) {
if !.Valid {
return nil, nil
}
, := LineCodec{}.PlanEncode(nil, 0, TextFormatCode, ).Encode(, nil)
if != nil {
return nil,
}
return string(),
}
type LineCodec struct{}
func (LineCodec) ( int16) bool {
return == TextFormatCode || == BinaryFormatCode
}
func (LineCodec) () int16 {
return BinaryFormatCode
}
func (LineCodec) ( *Map, uint32, int16, any) EncodePlan {
if , := .(LineValuer); ! {
return nil
}
switch {
case BinaryFormatCode:
return encodePlanLineCodecBinary{}
case TextFormatCode:
return encodePlanLineCodecText{}
}
return nil
}
type encodePlanLineCodecBinary struct{}
func (encodePlanLineCodecBinary) ( any, []byte) ( []byte, error) {
, := .(LineValuer).LineValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
= pgio.AppendUint64(, math.Float64bits(.A))
= pgio.AppendUint64(, math.Float64bits(.B))
= pgio.AppendUint64(, math.Float64bits(.C))
return , nil
}
type encodePlanLineCodecText struct{}
func (encodePlanLineCodecText) ( any, []byte) ( []byte, error) {
, := .(LineValuer).LineValue()
if != nil {
return nil,
}
if !.Valid {
return nil, nil
}
= append(, fmt.Sprintf(`{%s,%s,%s}`,
strconv.FormatFloat(.A, 'f', -1, 64),
strconv.FormatFloat(.B, 'f', -1, 64),
strconv.FormatFloat(.C, 'f', -1, 64),
)...)
return , nil
}
func (LineCodec) ( *Map, uint32, int16, any) ScanPlan {
switch {
case BinaryFormatCode:
switch .(type) {
case LineScanner:
return scanPlanBinaryLineToLineScanner{}
}
case TextFormatCode:
switch .(type) {
case LineScanner:
return scanPlanTextAnyToLineScanner{}
}
}
return nil
}
type scanPlanBinaryLineToLineScanner struct{}
func (scanPlanBinaryLineToLineScanner) ( []byte, any) error {
:= ().(LineScanner)
if == nil {
return .ScanLine(Line{})
}
if len() != 24 {
return fmt.Errorf("invalid length for line: %v", len())
}
:= binary.BigEndian.Uint64()
:= binary.BigEndian.Uint64([8:])
:= binary.BigEndian.Uint64([16:])
return .ScanLine(Line{
A: math.Float64frombits(),
B: math.Float64frombits(),
C: math.Float64frombits(),
Valid: true,
})
}
type scanPlanTextAnyToLineScanner struct{}
func (scanPlanTextAnyToLineScanner) ( []byte, any) error {
:= ().(LineScanner)
if == nil {
return .ScanLine(Line{})
}
if len() < 7 {
return fmt.Errorf("invalid length for line: %v", len())
}
:= strings.SplitN(string([1:len()-1]), ",", 3)
if len() < 3 {
return fmt.Errorf("invalid format for line")
}
, := strconv.ParseFloat([0], 64)
if != nil {
return
}
, := strconv.ParseFloat([1], 64)
if != nil {
return
}
, := strconv.ParseFloat([2], 64)
if != nil {
return
}
return .ScanLine(Line{A: , B: , C: , Valid: true})
}
func ( LineCodec) ( *Map, uint32, int16, []byte) (driver.Value, error) {
return codecDecodeToTextFormat(, , , , )
}
func ( LineCodec) ( *Map, uint32, int16, []byte) (any, error) {
if == nil {
return nil, nil
}
var Line
:= codecScan(, , , , , &)
if != nil {
return nil,
}
return , nil
}