From 6777e0294b5de77ea2022318b75b2ce7336b63cc Mon Sep 17 00:00:00 2001 From: bakmataliev Date: Tue, 15 Sep 2020 13:24:17 +0300 Subject: [PATCH] eliminate regex dep --- point.go | 57 +++++++++++++++++++++++---------------------------- point_test.go | 10 ++++----- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/point.go b/point.go index 37187117..55c6c8d1 100644 --- a/point.go +++ b/point.go @@ -1,11 +1,11 @@ package pgtype import ( + "bytes" "database/sql/driver" "encoding/binary" "fmt" "math" - "regexp" "strconv" "strings" @@ -23,8 +23,6 @@ type Point struct { Status Status } -var nullRE = regexp.MustCompile("^null$") - func (dst *Point) Set(src interface{}) error { if src == nil { dst.Status = Null @@ -47,34 +45,31 @@ func (dst *Point) Set(src interface{}) error { return nil } -var pointRE = regexp.MustCompile("^\\(\\d+\\.\\d+,\\s?\\d+\\.\\d+\\)$") -var chunkRE = regexp.MustCompile("\\d+\\.\\d+") - -func parsePoint(p []byte) (*Point, error) { - err := errors.Errorf("cannot parse %s", p) - if pointRE.Match(p) { - chunks := chunkRE.FindAll(p, 2) - if len(chunks) != 2 { - return nil, err - } - x, xErr := strconv.ParseFloat(string(chunks[0]), 64) - y, yErr := strconv.ParseFloat(string(chunks[1]), 64) - if xErr != nil || yErr != nil { - return nil, err - } - return &Point{ - P: Vec2{ - X: x, - Y: y, - }, - Status: Present, - }, nil - } else if nullRE.Match(p) { - return &Point{ - Status: Null, - }, nil +func parsePoint(src []byte) (*Point, error) { + if src == nil || bytes.Compare(src, []byte("null")) == 0 { + return &Point{Status: Null}, nil } - return nil, err + + if len(src) < 5 { + return nil, errors.Errorf("invalid length for point: %v", len(src)) + } + + parts := strings.SplitN(string(src[1:len(src)-1]), ",", 2) + if len(parts) < 2 { + return nil, errors.Errorf("invalid format for point") + } + + x, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return nil, err + } + + y, err := strconv.ParseFloat(parts[1], 64) + if err != nil { + return nil, err + } + + return &Point{P: Vec2{x, y}, Status: Present}, nil } func (dst Point) Get() interface{} { @@ -195,7 +190,7 @@ func (src Point) Value() (driver.Value, error) { func (src Point) MarshalJSON() ([]byte, error) { switch src.Status { case Present: - return []byte(fmt.Sprintf("(%g, %g)", src.P.X, src.P.Y)), nil + return []byte(fmt.Sprintf("(%g,%g)", src.P.X, src.P.Y)), nil case Null: return []byte("null"), nil case Undefined: diff --git a/point_test.go b/point_test.go index 9a659cbc..3601cf02 100644 --- a/point_test.go +++ b/point_test.go @@ -25,13 +25,13 @@ func TestPoint_Set(t *testing.T) { }{ { name: "first", - arg: "(12312.123123, 123123.123123)", + arg: "(12312.123123,123123.123123)", status: pgtype.Present, wantErr: false, }, { name: "second", - arg: "(1231s2.123123, 123123.123123)", + arg: "(1231s2.123123,123123.123123)", status: pgtype.Undefined, wantErr: true, }, @@ -83,7 +83,7 @@ func TestPoint_MarshalJSON(t *testing.T) { P: pgtype.Vec2{X: 12.245, Y: 432.12}, Status: pgtype.Present, }, - want: []byte("(12.245, 432.12)"), + want: []byte("(12.245,432.12)"), wantErr: false, }, { @@ -120,13 +120,13 @@ func TestPoint_UnmarshalJSON(t *testing.T) { { name: "first", status: pgtype.Present, - arg: []byte("(123.123, 54.12)"), + arg: []byte("(123.123,54.12)"), wantErr: false, }, { name: "second", status: pgtype.Undefined, - arg: []byte("(123.123, 54.1sad2)"), + arg: []byte("(123.123,54.1sad2)"), wantErr: true, }, {