...

Source file src/github.com/go-redis/redis/internal/proto/scan.go

Documentation: github.com/go-redis/redis/internal/proto

     1  package proto
     2  
     3  import (
     4  	"encoding"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/go-redis/redis/internal/util"
     9  )
    10  
    11  func Scan(b []byte, v interface{}) error {
    12  	switch v := v.(type) {
    13  	case nil:
    14  		return fmt.Errorf("redis: Scan(nil)")
    15  	case *string:
    16  		*v = util.BytesToString(b)
    17  		return nil
    18  	case *[]byte:
    19  		*v = b
    20  		return nil
    21  	case *int:
    22  		var err error
    23  		*v, err = util.Atoi(b)
    24  		return err
    25  	case *int8:
    26  		n, err := util.ParseInt(b, 10, 8)
    27  		if err != nil {
    28  			return err
    29  		}
    30  		*v = int8(n)
    31  		return nil
    32  	case *int16:
    33  		n, err := util.ParseInt(b, 10, 16)
    34  		if err != nil {
    35  			return err
    36  		}
    37  		*v = int16(n)
    38  		return nil
    39  	case *int32:
    40  		n, err := util.ParseInt(b, 10, 32)
    41  		if err != nil {
    42  			return err
    43  		}
    44  		*v = int32(n)
    45  		return nil
    46  	case *int64:
    47  		n, err := util.ParseInt(b, 10, 64)
    48  		if err != nil {
    49  			return err
    50  		}
    51  		*v = n
    52  		return nil
    53  	case *uint:
    54  		n, err := util.ParseUint(b, 10, 64)
    55  		if err != nil {
    56  			return err
    57  		}
    58  		*v = uint(n)
    59  		return nil
    60  	case *uint8:
    61  		n, err := util.ParseUint(b, 10, 8)
    62  		if err != nil {
    63  			return err
    64  		}
    65  		*v = uint8(n)
    66  		return nil
    67  	case *uint16:
    68  		n, err := util.ParseUint(b, 10, 16)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		*v = uint16(n)
    73  		return nil
    74  	case *uint32:
    75  		n, err := util.ParseUint(b, 10, 32)
    76  		if err != nil {
    77  			return err
    78  		}
    79  		*v = uint32(n)
    80  		return nil
    81  	case *uint64:
    82  		n, err := util.ParseUint(b, 10, 64)
    83  		if err != nil {
    84  			return err
    85  		}
    86  		*v = n
    87  		return nil
    88  	case *float32:
    89  		n, err := util.ParseFloat(b, 32)
    90  		if err != nil {
    91  			return err
    92  		}
    93  		*v = float32(n)
    94  		return err
    95  	case *float64:
    96  		var err error
    97  		*v, err = util.ParseFloat(b, 64)
    98  		return err
    99  	case *bool:
   100  		*v = len(b) == 1 && b[0] == '1'
   101  		return nil
   102  	case encoding.BinaryUnmarshaler:
   103  		return v.UnmarshalBinary(b)
   104  	default:
   105  		return fmt.Errorf(
   106  			"redis: can't unmarshal %T (consider implementing BinaryUnmarshaler)", v)
   107  	}
   108  }
   109  
   110  func ScanSlice(data []string, slice interface{}) error {
   111  	v := reflect.ValueOf(slice)
   112  	if !v.IsValid() {
   113  		return fmt.Errorf("redis: ScanSlice(nil)")
   114  	}
   115  	if v.Kind() != reflect.Ptr {
   116  		return fmt.Errorf("redis: ScanSlice(non-pointer %T)", slice)
   117  	}
   118  	v = v.Elem()
   119  	if v.Kind() != reflect.Slice {
   120  		return fmt.Errorf("redis: ScanSlice(non-slice %T)", slice)
   121  	}
   122  
   123  	next := makeSliceNextElemFunc(v)
   124  	for i, s := range data {
   125  		elem := next()
   126  		if err := Scan([]byte(s), elem.Addr().Interface()); err != nil {
   127  			err = fmt.Errorf("redis: ScanSlice index=%d value=%q failed: %s", i, s, err)
   128  			return err
   129  		}
   130  	}
   131  
   132  	return nil
   133  }
   134  
   135  func makeSliceNextElemFunc(v reflect.Value) func() reflect.Value {
   136  	elemType := v.Type().Elem()
   137  
   138  	if elemType.Kind() == reflect.Ptr {
   139  		elemType = elemType.Elem()
   140  		return func() reflect.Value {
   141  			if v.Len() < v.Cap() {
   142  				v.Set(v.Slice(0, v.Len()+1))
   143  				elem := v.Index(v.Len() - 1)
   144  				if elem.IsNil() {
   145  					elem.Set(reflect.New(elemType))
   146  				}
   147  				return elem.Elem()
   148  			}
   149  
   150  			elem := reflect.New(elemType)
   151  			v.Set(reflect.Append(v, elem))
   152  			return elem.Elem()
   153  		}
   154  	}
   155  
   156  	zero := reflect.Zero(elemType)
   157  	return func() reflect.Value {
   158  		if v.Len() < v.Cap() {
   159  			v.Set(v.Slice(0, v.Len()+1))
   160  			return v.Index(v.Len() - 1)
   161  		}
   162  
   163  		v.Set(reflect.Append(v, zero))
   164  		return v.Index(v.Len() - 1)
   165  	}
   166  }
   167  

View as plain text