1package pgtype 2 3import ( 4 "database/sql/driver" 5 "encoding/binary" 6 "fmt" 7 "math" 8 "strconv" 9 "strings" 10 11 "github.com/jackc/pgio" 12) 13 14type Circle struct { 15 P Vec2 16 R float64 17 Status Status 18} 19 20func (dst *Circle) Set(src interface{}) error { 21 return fmt.Errorf("cannot convert %v to Circle", src) 22} 23 24func (dst Circle) Get() interface{} { 25 switch dst.Status { 26 case Present: 27 return dst 28 case Null: 29 return nil 30 default: 31 return dst.Status 32 } 33} 34 35func (src *Circle) AssignTo(dst interface{}) error { 36 return fmt.Errorf("cannot assign %v to %T", src, dst) 37} 38 39func (dst *Circle) DecodeText(ci *ConnInfo, src []byte) error { 40 if src == nil { 41 *dst = Circle{Status: Null} 42 return nil 43 } 44 45 if len(src) < 9 { 46 return fmt.Errorf("invalid length for Circle: %v", len(src)) 47 } 48 49 str := string(src[2:]) 50 end := strings.IndexByte(str, ',') 51 x, err := strconv.ParseFloat(str[:end], 64) 52 if err != nil { 53 return err 54 } 55 56 str = str[end+1:] 57 end = strings.IndexByte(str, ')') 58 59 y, err := strconv.ParseFloat(str[:end], 64) 60 if err != nil { 61 return err 62 } 63 64 str = str[end+2 : len(str)-1] 65 66 r, err := strconv.ParseFloat(str, 64) 67 if err != nil { 68 return err 69 } 70 71 *dst = Circle{P: Vec2{x, y}, R: r, Status: Present} 72 return nil 73} 74 75func (dst *Circle) DecodeBinary(ci *ConnInfo, src []byte) error { 76 if src == nil { 77 *dst = Circle{Status: Null} 78 return nil 79 } 80 81 if len(src) != 24 { 82 return fmt.Errorf("invalid length for Circle: %v", len(src)) 83 } 84 85 x := binary.BigEndian.Uint64(src) 86 y := binary.BigEndian.Uint64(src[8:]) 87 r := binary.BigEndian.Uint64(src[16:]) 88 89 *dst = Circle{ 90 P: Vec2{math.Float64frombits(x), math.Float64frombits(y)}, 91 R: math.Float64frombits(r), 92 Status: Present, 93 } 94 return nil 95} 96 97func (src Circle) EncodeText(ci *ConnInfo, buf []byte) ([]byte, error) { 98 switch src.Status { 99 case Null: 100 return nil, nil 101 case Undefined: 102 return nil, errUndefined 103 } 104 105 buf = append(buf, fmt.Sprintf(`<(%s,%s),%s>`, 106 strconv.FormatFloat(src.P.X, 'f', -1, 64), 107 strconv.FormatFloat(src.P.Y, 'f', -1, 64), 108 strconv.FormatFloat(src.R, 'f', -1, 64), 109 )...) 110 111 return buf, nil 112} 113 114func (src Circle) EncodeBinary(ci *ConnInfo, buf []byte) ([]byte, error) { 115 switch src.Status { 116 case Null: 117 return nil, nil 118 case Undefined: 119 return nil, errUndefined 120 } 121 122 buf = pgio.AppendUint64(buf, math.Float64bits(src.P.X)) 123 buf = pgio.AppendUint64(buf, math.Float64bits(src.P.Y)) 124 buf = pgio.AppendUint64(buf, math.Float64bits(src.R)) 125 return buf, nil 126} 127 128// Scan implements the database/sql Scanner interface. 129func (dst *Circle) Scan(src interface{}) error { 130 if src == nil { 131 *dst = Circle{Status: Null} 132 return nil 133 } 134 135 switch src := src.(type) { 136 case string: 137 return dst.DecodeText(nil, []byte(src)) 138 case []byte: 139 srcCopy := make([]byte, len(src)) 140 copy(srcCopy, src) 141 return dst.DecodeText(nil, srcCopy) 142 } 143 144 return fmt.Errorf("cannot scan %T", src) 145} 146 147// Value implements the database/sql/driver Valuer interface. 148func (src Circle) Value() (driver.Value, error) { 149 return EncodeValueText(src) 150} 151