Skip to content
This repository has been archived by the owner on Apr 2, 2021. It is now read-only.

add resp3 protocol part 2(double and big number) #79

Merged
merged 1 commit into from
Aug 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions internal/protcl/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,22 @@ func (e *ErrUnexpectString) Recoverable() bool {
func (e *ErrUnexpectString) Error() string {
return fmt.Sprintf("unexpect string: %s", e.Str)
}

// ErrConvertType is for convert value to another type fail
type ErrConvertType struct {
Type string
Err error
Value interface{}
}

// Recoverable whether error is recoverable or not
func (e *ErrConvertType) Recoverable() bool {
return true
}

func (e *ErrConvertType) Error() string {
if e.Err == nil {
return fmt.Sprintf("convert %v to %s fail", e.Value, e.Type)
}
return fmt.Sprintf("convert %v to %s fail, because of %s", e.Value, e.Type, e.Err)
}
27 changes: 27 additions & 0 deletions internal/protcl/resp3.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package protcl
import (
"bufio"
"fmt"
"math/big"
"strconv"
)

Expand Down Expand Up @@ -32,6 +33,8 @@ type Resp3 struct {
Str string
Integer int
Boolean bool
Double float64
BigInt *big.Int
}

func (r *Resp3) String() string {
Expand All @@ -42,6 +45,10 @@ func (r *Resp3) String() string {
return "(error) " + r.Str
case Resp3Number:
return "(integer) " + strconv.Itoa(r.Integer)
case Resp3Double:
return "(double) " + strconv.FormatFloat(r.Double, 'f', -1, 64)
case Resp3BigNumber:
return "(big number) " + r.BigInt.String()
case Resp3Null:
return "(null)"
case Resp3Boolean:
Expand Down Expand Up @@ -96,6 +103,26 @@ func (r *Resp3Parser) Parse() (*Resp3, error) {
return nil, err
}
return &Resp3{Type: b, Integer: integer}, nil
case Resp3Double:
str, err := r.stringBeforeLF()
if err != nil {
return nil, err
}
f, err := strconv.ParseFloat(str, 64)
if err != nil {
return nil, &ErrConvertType{Type: "double", Value: str, Err: err}
}
return &Resp3{Type: b, Double: f}, nil
case Resp3BigNumber:
str, err := r.stringBeforeLF()
if err != nil {
return nil, err
}
bigInt, ok := big.NewInt(0).SetString(str, 10)
if !ok {
return nil, &ErrConvertType{Type: "Big Number", Value: str}
}
return &Resp3{Type: b, BigInt: bigInt}, nil
case Resp3Null:
if _, err := r.readLengthBytesWithLF(0); err != nil {
return nil, err
Expand Down
13 changes: 13 additions & 0 deletions internal/protcl/resp3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ func TestResp3Parser(t *testing.T) {
testResp3Parser(t, ":0\n", `(integer) 0`)
testResp3Parser(t, ":100\n", `(integer) 100`)

// double
testResp3Parser(t, ",-1\n", `(double) -1`)
testResp3Parser(t, ",0\n", `(double) 0`)
testResp3Parser(t, ",10\n", `(double) 10`)
testResp3Parser(t, ",.1\n", `(double) 0.1`)
testResp3Parser(t, ",1.23\n", `(double) 1.23`)
testResp3Parser(t, ",1.\n", `(double) 1`)
testResp3Error(t, ",invalid\n", `convert invalid to double fail, because of strconv.ParseFloat: parsing "invalid": invalid syntax`)

// big number
testResp3Parser(t, "(3492890328409238509324850943850943825024385\n", `(big number) 3492890328409238509324850943850943825024385`)
testResp3Error(t, "(invalid string\n", `convert invalid string to Big Number fail`)

// null
testResp3Parser(t, "_\n", "(null)")

Expand Down