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

Commit

Permalink
add resp3 protocol part 3(array and set) (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
chyroc authored and kasvith committed Aug 27, 2018
1 parent bd4a4a5 commit 91f7cd8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
51 changes: 42 additions & 9 deletions internal/protcl/resp3.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math/big"
"strconv"
"strings"
)

// resp3 protocol type
Expand Down Expand Up @@ -35,30 +36,48 @@ type Resp3 struct {
Boolean bool
Double float64
BigInt *big.Int
Elems []*Resp3
}

func (r *Resp3) String() string {
return r.string("")
}

func (r *Resp3) string(pre string) string {
switch r.Type {
case RepSimpleString, Resp3BlobString:
return fmt.Sprintf("%q", r.Str)
return fmt.Sprintf("%s%q", pre, r.Str)
case Resp3SimpleError, Resp3BolbError:
return "(error) " + r.Str
return pre + "(error) " + r.Str
case Resp3Number:
return "(integer) " + strconv.Itoa(r.Integer)
return pre + "(integer) " + strconv.Itoa(r.Integer)
case Resp3Double:
return "(double) " + strconv.FormatFloat(r.Double, 'f', -1, 64)
return pre + "(double) " + strconv.FormatFloat(r.Double, 'f', -1, 64)
case Resp3BigNumber:
return "(big number) " + r.BigInt.String()
return pre + "(big number) " + r.BigInt.String()
case Resp3Null:
return "(null)"
return pre + "(null)"
case Resp3Boolean:
if r.Boolean {
return "(boolean) true"
return pre + "(boolean) true"
}
return pre + "(boolean) false"
case Resp3Array, Resp3Set:
str := new(strings.Builder)
str.WriteString(pre)
if r.Type == Resp3Array {
str.WriteString("(array)")
} else {
str.WriteString("(set)")
}
return "(boolean) false"
for _, elem := range r.Elems {
str.WriteString("\n")
str.WriteString(elem.string(pre + "\t"))
}
return str.String()
}

return "(error) unknown protocol type: " + string(r.Type)
return pre + "(error) unknown protocol type: " + string(r.Type)
}

// Resp3Parser is for parser resp3 protocol
Expand Down Expand Up @@ -141,6 +160,20 @@ func (r *Resp3Parser) Parse() (*Resp3, error) {
return &Resp3{Type: b, Boolean: false}, nil
}
return nil, &ErrUnexpectString{Str: "t/f"}
case Resp3Array, Resp3Set:
length, err := r.intBeforeLF()
if err != nil {
return nil, err
}
resp := &Resp3{Type: b}
for i := 0; i < length; i++ {
elem, err := r.Parse()
if err != nil {
return nil, err
}
resp.Elems = append(resp.Elems, elem)
}
return resp, nil
}

return nil, &ErrProtocolType{Type: b}
Expand Down
10 changes: 10 additions & 0 deletions internal/protcl/resp3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,14 @@ func TestResp3Parser(t *testing.T) {
testResp3Parser(t, "#f\n", `(boolean) false`)
testResp3Error(t, "#x\n", `unexpect string: t/f`)
testResp3Error(t, "#\n", `unexpected line end`)

// array
testResp3Error(t, "*3\n:1\n:2\n", "EOF")
testResp3Parser(t, "*3\n:1\n:2\n:3\n", "(array)\n\t(integer) 1\n\t(integer) 2\n\t(integer) 3")
testResp3Parser(t, "*2\n*3\n:1\n$5\nhello\n:2\n#f\n", "(array)\n\t(array)\n\t\t(integer) 1\n\t\t\"hello\"\n\t\t(integer) 2\n\t(boolean) false")

// set
testResp3Error(t, "~3\n:1\n:2\n", "EOF")
testResp3Parser(t, "~3\n:1\n:2\n:3\n", "(set)\n\t(integer) 1\n\t(integer) 2\n\t(integer) 3")
testResp3Parser(t, "~2\n*3\n:1\n$5\nhello\n:2\n#f\n", "(set)\n\t(array)\n\t\t(integer) 1\n\t\t\"hello\"\n\t\t(integer) 2\n\t(boolean) false")
}

0 comments on commit 91f7cd8

Please sign in to comment.