in marshal.go [2281:2386]
func unmarshalTuple(info TypeInfo, data []byte, value interface{}) error {
if v, ok := value.(Unmarshaler); ok {
return v.UnmarshalCQL(info, data)
}
tuple := info.(TupleTypeInfo)
switch v := value.(type) {
case []interface{}:
for i, elem := range tuple.Elems {
// each element inside data is a [bytes]
var p []byte
if len(data) >= 4 {
p, data = readBytes(data)
}
err := Unmarshal(elem, p, v[i])
if err != nil {
return err
}
}
return nil
}
rv := reflect.ValueOf(value)
if rv.Kind() != reflect.Ptr {
return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
}
rv = rv.Elem()
t := rv.Type()
k := t.Kind()
switch k {
case reflect.Struct:
if v := t.NumField(); v != len(tuple.Elems) {
return unmarshalErrorf("can not unmarshal tuple into struct %v, not enough fields have %d need %d", t, v, len(tuple.Elems))
}
for i, elem := range tuple.Elems {
var p []byte
if len(data) >= 4 {
p, data = readBytes(data)
}
v, err := elem.NewWithError()
if err != nil {
return err
}
if err := Unmarshal(elem, p, v); err != nil {
return err
}
switch rv.Field(i).Kind() {
case reflect.Ptr:
if p != nil {
rv.Field(i).Set(reflect.ValueOf(v))
} else {
rv.Field(i).Set(reflect.Zero(reflect.TypeOf(v)))
}
default:
rv.Field(i).Set(reflect.ValueOf(v).Elem())
}
}
return nil
case reflect.Slice, reflect.Array:
if k == reflect.Array {
size := rv.Len()
if size != len(tuple.Elems) {
return unmarshalErrorf("can not unmarshal tuple into array of length %d need %d elements", size, len(tuple.Elems))
}
} else {
rv.Set(reflect.MakeSlice(t, len(tuple.Elems), len(tuple.Elems)))
}
for i, elem := range tuple.Elems {
var p []byte
if len(data) >= 4 {
p, data = readBytes(data)
}
v, err := elem.NewWithError()
if err != nil {
return err
}
if err := Unmarshal(elem, p, v); err != nil {
return err
}
switch rv.Index(i).Kind() {
case reflect.Ptr:
if p != nil {
rv.Index(i).Set(reflect.ValueOf(v))
} else {
rv.Index(i).Set(reflect.Zero(reflect.TypeOf(v)))
}
default:
rv.Index(i).Set(reflect.ValueOf(v).Elem())
}
}
return nil
}
return unmarshalErrorf("cannot unmarshal %s into %T. Accepted types: *struct, []interface{}, *array, *slice, Unmarshaler.", info, value)
}