package hscan
import (
"errors"
"fmt"
"reflect"
"strconv"
)
type decoderFunc func (reflect .Value , string ) error
type Scanner interface {
ScanRedis (s string ) error
}
var (
decoders = []decoderFunc {
reflect .Bool : decodeBool ,
reflect .Int : decodeInt ,
reflect .Int8 : decodeInt8 ,
reflect .Int16 : decodeInt16 ,
reflect .Int32 : decodeInt32 ,
reflect .Int64 : decodeInt64 ,
reflect .Uint : decodeUint ,
reflect .Uint8 : decodeUint8 ,
reflect .Uint16 : decodeUint16 ,
reflect .Uint32 : decodeUint32 ,
reflect .Uint64 : decodeUint64 ,
reflect .Float32 : decodeFloat32 ,
reflect .Float64 : decodeFloat64 ,
reflect .Complex64 : decodeUnsupported ,
reflect .Complex128 : decodeUnsupported ,
reflect .Array : decodeUnsupported ,
reflect .Chan : decodeUnsupported ,
reflect .Func : decodeUnsupported ,
reflect .Interface : decodeUnsupported ,
reflect .Map : decodeUnsupported ,
reflect .Ptr : decodeUnsupported ,
reflect .Slice : decodeSlice ,
reflect .String : decodeString ,
reflect .Struct : decodeUnsupported ,
reflect .UnsafePointer : decodeUnsupported ,
}
globalStructMap = newStructMap ()
)
func Struct (dst interface {}) (StructValue , error ) {
v := reflect .ValueOf (dst )
if v .Kind () != reflect .Ptr || v .IsNil () {
return StructValue {}, fmt .Errorf ("redis.Scan(non-pointer %T)" , dst )
}
v = v .Elem ()
if v .Kind () != reflect .Struct {
return StructValue {}, fmt .Errorf ("redis.Scan(non-struct %T)" , dst )
}
return StructValue {
spec : globalStructMap .get (v .Type ()),
value : v ,
}, nil
}
func Scan (dst interface {}, keys []interface {}, vals []interface {}) error {
if len (keys ) != len (vals ) {
return errors .New ("args should have the same number of keys and vals" )
}
strct , err := Struct (dst )
if err != nil {
return err
}
for i := 0 ; i < len (vals ); i ++ {
key , ok := keys [i ].(string )
if !ok {
continue
}
val , ok := vals [i ].(string )
if !ok {
continue
}
if err := strct .Scan (key , val ); err != nil {
return err
}
}
return nil
}
func decodeBool(f reflect .Value , s string ) error {
b , err := strconv .ParseBool (s )
if err != nil {
return err
}
f .SetBool (b )
return nil
}
func decodeInt8(f reflect .Value , s string ) error {
return decodeNumber (f , s , 8 )
}
func decodeInt16(f reflect .Value , s string ) error {
return decodeNumber (f , s , 16 )
}
func decodeInt32(f reflect .Value , s string ) error {
return decodeNumber (f , s , 32 )
}
func decodeInt64(f reflect .Value , s string ) error {
return decodeNumber (f , s , 64 )
}
func decodeInt(f reflect .Value , s string ) error {
return decodeNumber (f , s , 0 )
}
func decodeNumber(f reflect .Value , s string , bitSize int ) error {
v , err := strconv .ParseInt (s , 10 , bitSize )
if err != nil {
return err
}
f .SetInt (v )
return nil
}
func decodeUint8(f reflect .Value , s string ) error {
return decodeUnsignedNumber (f , s , 8 )
}
func decodeUint16(f reflect .Value , s string ) error {
return decodeUnsignedNumber (f , s , 16 )
}
func decodeUint32(f reflect .Value , s string ) error {
return decodeUnsignedNumber (f , s , 32 )
}
func decodeUint64(f reflect .Value , s string ) error {
return decodeUnsignedNumber (f , s , 64 )
}
func decodeUint(f reflect .Value , s string ) error {
return decodeUnsignedNumber (f , s , 0 )
}
func decodeUnsignedNumber(f reflect .Value , s string , bitSize int ) error {
v , err := strconv .ParseUint (s , 10 , bitSize )
if err != nil {
return err
}
f .SetUint (v )
return nil
}
func decodeFloat32(f reflect .Value , s string ) error {
v , err := strconv .ParseFloat (s , 32 )
if err != nil {
return err
}
f .SetFloat (v )
return nil
}
func decodeFloat64(f reflect .Value , s string ) error {
v , err := strconv .ParseFloat (s , 64 )
if err != nil {
return err
}
f .SetFloat (v )
return nil
}
func decodeString(f reflect .Value , s string ) error {
f .SetString (s )
return nil
}
func decodeSlice(f reflect .Value , s string ) error {
if f .Type ().Elem ().Kind () == reflect .Uint8 {
f .SetBytes ([]byte (s ))
}
return nil
}
func decodeUnsupported(v reflect .Value , s string ) error {
return fmt .Errorf ("redis.Scan(unsupported %s)" , v .Type ())
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .