forked from mirror/redcon
Added AppendAny
This commit is contained in:
parent
72acf6b980
commit
a389b6ca04
100
append.go
100
append.go
|
@ -1,6 +1,9 @@
|
||||||
package redcon
|
package redcon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -348,3 +351,100 @@ func AppendBulkUint(b []byte, x uint64) []byte {
|
||||||
b = b[:mark1+(mark3-mark2)]
|
b = b[:mark1+(mark3-mark2)]
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendAny appends any type to valid Redis type
|
||||||
|
func AppendAny(b []byte, v interface{}) []byte {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case nil:
|
||||||
|
b = AppendNull(b)
|
||||||
|
case error:
|
||||||
|
b = AppendError(b, "ERR "+v.Error())
|
||||||
|
case string:
|
||||||
|
b = AppendBulkString(b, v)
|
||||||
|
case []byte:
|
||||||
|
b = AppendBulk(b, v)
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
b = AppendInt(b, 1)
|
||||||
|
} else {
|
||||||
|
b = AppendInt(b, 0)
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
b = AppendInt(b, int64(v))
|
||||||
|
case int8:
|
||||||
|
b = AppendInt(b, int64(v))
|
||||||
|
case int16:
|
||||||
|
b = AppendInt(b, int64(v))
|
||||||
|
case int32:
|
||||||
|
b = AppendInt(b, int64(v))
|
||||||
|
case int64:
|
||||||
|
b = AppendInt(b, int64(v))
|
||||||
|
case uint:
|
||||||
|
b = AppendUint(b, uint64(v))
|
||||||
|
case uint8:
|
||||||
|
b = AppendUint(b, uint64(v))
|
||||||
|
case uint16:
|
||||||
|
b = AppendUint(b, uint64(v))
|
||||||
|
case uint32:
|
||||||
|
b = AppendUint(b, uint64(v))
|
||||||
|
case uint64:
|
||||||
|
b = AppendUint(b, uint64(v))
|
||||||
|
case float32:
|
||||||
|
b = AppendBulkFloat(b, float64(v))
|
||||||
|
case float64:
|
||||||
|
b = AppendBulkFloat(b, float64(v))
|
||||||
|
default:
|
||||||
|
vv := reflect.ValueOf(v)
|
||||||
|
switch vv.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
n := vv.Len()
|
||||||
|
b = AppendArray(b, n)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
b = AppendAny(b, vv.Index(i).Interface())
|
||||||
|
}
|
||||||
|
case reflect.Map:
|
||||||
|
n := vv.Len()
|
||||||
|
b = AppendArray(b, n*2)
|
||||||
|
var i int
|
||||||
|
var strKey bool
|
||||||
|
var strsKeyItems []strKeyItem
|
||||||
|
|
||||||
|
iter := vv.MapRange()
|
||||||
|
for iter.Next() {
|
||||||
|
key := iter.Key().Interface()
|
||||||
|
if i == 0 {
|
||||||
|
if _, ok := key.(string); ok {
|
||||||
|
strKey = true
|
||||||
|
strsKeyItems = make([]strKeyItem, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strKey {
|
||||||
|
strsKeyItems[i] = strKeyItem{
|
||||||
|
key.(string), iter.Value().Interface(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b = AppendAny(b, key)
|
||||||
|
b = AppendAny(b, iter.Value().Interface())
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if strKey {
|
||||||
|
sort.Slice(strsKeyItems, func(i, j int) bool {
|
||||||
|
return strsKeyItems[i].key < strsKeyItems[j].key
|
||||||
|
})
|
||||||
|
for _, item := range strsKeyItems {
|
||||||
|
b = AppendBulkString(b, item.key)
|
||||||
|
b = AppendAny(b, item.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
b = AppendBulkString(b, fmt.Sprint(v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
type strKeyItem struct {
|
||||||
|
key string
|
||||||
|
value interface{}
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ type Conn interface {
|
||||||
WriteNull()
|
WriteNull()
|
||||||
// WriteRaw writes raw data to the client.
|
// WriteRaw writes raw data to the client.
|
||||||
WriteRaw(data []byte)
|
WriteRaw(data []byte)
|
||||||
|
// WriteAny writes any type to the client.
|
||||||
|
WriteAny(any interface{})
|
||||||
// Context returns a user-defined context
|
// Context returns a user-defined context
|
||||||
Context() interface{}
|
Context() interface{}
|
||||||
// SetContext sets a user-defined context
|
// SetContext sets a user-defined context
|
||||||
|
@ -442,6 +444,7 @@ func (c *conn) WriteError(msg string) { c.wr.WriteError(msg) }
|
||||||
func (c *conn) WriteArray(count int) { c.wr.WriteArray(count) }
|
func (c *conn) WriteArray(count int) { c.wr.WriteArray(count) }
|
||||||
func (c *conn) WriteNull() { c.wr.WriteNull() }
|
func (c *conn) WriteNull() { c.wr.WriteNull() }
|
||||||
func (c *conn) WriteRaw(data []byte) { c.wr.WriteRaw(data) }
|
func (c *conn) WriteRaw(data []byte) { c.wr.WriteRaw(data) }
|
||||||
|
func (c *conn) WriteAny(v interface{}) { c.wr.WriteAny(v) }
|
||||||
func (c *conn) RemoteAddr() string { return c.addr }
|
func (c *conn) RemoteAddr() string { return c.addr }
|
||||||
func (c *conn) ReadPipeline() []Command {
|
func (c *conn) ReadPipeline() []Command {
|
||||||
cmds := c.cmds
|
cmds := c.cmds
|
||||||
|
@ -633,6 +636,11 @@ func (w *Writer) WriteRaw(data []byte) {
|
||||||
w.b = append(w.b, data...)
|
w.b = append(w.b, data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteAny writes any type to client.
|
||||||
|
func (w *Writer) WriteAny(v interface{}) {
|
||||||
|
w.b = AppendAny(w.b, v)
|
||||||
|
}
|
||||||
|
|
||||||
// Reader represent a reader for RESP or telnet commands.
|
// Reader represent a reader for RESP or telnet commands.
|
||||||
type Reader struct {
|
type Reader struct {
|
||||||
rd *bufio.Reader
|
rd *bufio.Reader
|
||||||
|
|
Loading…
Reference in New Issue