From d98d0d723c43ba60ef73c24688d021d18ebea61b Mon Sep 17 00:00:00 2001 From: tidwall Date: Wed, 3 Aug 2022 04:51:39 -0700 Subject: [PATCH] Added Map and removed receiver pointer --- resp.go | 38 ++++++++++++++++++++++++++++++++------ resp_test.go | 23 +++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/resp.go b/resp.go index 07700bf..d06eb43 100644 --- a/resp.go +++ b/resp.go @@ -28,7 +28,7 @@ type RESP struct { } // ForEach iterates over each Array element -func (r *RESP) ForEach(iter func(resp RESP) bool) { +func (r RESP) ForEach(iter func(resp RESP) bool) { data := r.Data for i := 0; i < r.Count; i++ { n, resp := ReadNextRESP(data) @@ -39,24 +39,50 @@ func (r *RESP) ForEach(iter func(resp RESP) bool) { } } -func (r *RESP) Bytes() []byte { +func (r RESP) Bytes() []byte { + if r.Type == Array { + return r.Raw + } return r.Data } -func (r *RESP) String() string { - return string(r.Data) +func (r RESP) String() string { + return string(r.Bytes()) } -func (r *RESP) Int() int64 { +func (r RESP) Int() int64 { x, _ := strconv.ParseInt(r.String(), 10, 64) return x } -func (r *RESP) Float() float64 { +func (r RESP) Float() float64 { x, _ := strconv.ParseFloat(r.String(), 10) return x } +// Map returns a key/value map of an Array. +// The receiver RESP must be an Array with an equal number of values, where +// the value of the key is followed by the key. +// Example: key1,value1,key2,value2,key3,value3 +func (r RESP) Map() map[string]RESP { + if r.Type != Array { + return nil + } + var n int + var key string + m := make(map[string]RESP) + r.ForEach(func(resp RESP) bool { + if n&1 == 0 { + key = resp.String() + } else { + m[key] = resp + } + n++ + return true + }) + return m +} + // ReadNextRESP returns the next resp in b and returns the number of bytes the // took up the result. func ReadNextRESP(b []byte) (n int, resp RESP) { diff --git a/resp_test.go b/resp_test.go index 462fcda..f027805 100644 --- a/resp_test.go +++ b/resp_test.go @@ -250,3 +250,26 @@ func TestAppendBulkUint(t *testing.T) { t.Fatalf("expected '%s', got '%s'", exp, b) } } + +func TestArrayMap(t *testing.T) { + var dst []byte + dst = AppendArray(dst, 4) + dst = AppendBulkString(dst, "key1") + dst = AppendBulkString(dst, "val1") + dst = AppendBulkString(dst, "key2") + dst = AppendBulkString(dst, "val2") + n, resp := ReadNextRESP(dst) + if n != len(dst) { + t.Fatalf("expected '%d', got '%d'", len(dst), n) + } + m := resp.Map() + if len(m) != 2 { + t.Fatalf("expected '%d', got '%d'", 2, len(m)) + } + if m["key1"].String() != "val1" { + t.Fatalf("expected '%s', got '%s'", "val1", m["key1"].String()) + } + if m["key2"].String() != "val2" { + t.Fatalf("expected '%s', got '%s'", "val2", m["key2"].String()) + } +}